2014-02-13 28 views
7

我已經成功實現了jQueryUI可拖動,但只要添加hammer.js代碼,可拖動的代碼就不再起作用。Draggable代碼不能與hammer.js一起使用

它不是一旦我包含hammer.js,但只要我使用腳本。

這是爲什麼?我怎樣才能讓他們都能工作?

無論是拖動和錘子應用於.dataCard#main

可拖動代碼工作正常這裏(用鐵錘實施註釋掉):http://goo.gl/MO5Pde

下面是可拖動的代碼示例:

$('#main').draggable({ 
    axis:'y', 
    revert:true, 
    start: function(event, ui){ 
     topValue = ui.position.top; 
    }, 
    drag: function(event, ui){ 
      if(pastBreakpoint === false){ 
       $('#searchInput').blur(); 
       if(topValue > ui.position.top) return false; 
      if(ui.position.top >= 161){ 
       if(pastBreakpoint === false){ 
       pastBreakpoint = true; 
        if($('.loadingRefresh').length === 0) $('#main').before('<div class="loadingRefresh"></div>'); 
        else{ 
        $('.loadingRefresh').remove(); 
         $('#main').before('<div class="loadingRefresh"></div>'); 
        } 
        $('.loadingRefresh').fadeIn(); 
        $('#main').mouseup(); 
        setTimeout(function(){ 
         location.reload(); 
        }, 1000); 
       } 
       } 
      } 
     } 
    }); 

這是未註釋的錘碼和可拖動的代碼不起作用:http://goo.gl/994pxF

這裏是錘代碼:

var hammertime = Hammer(document.getElementById('main'), { 
    transform_always_block: true, 
    transform_min_scale: 0 
}); 

var posX = 0, 
    posY = 0, 
    lastPosX = 0, 
    lastPosY = 0, 
    bufferX = 0, 
    bufferY = 0, 
    scale = 1, 
    last_scale = 1; 


hammertime.on('touch transform transformend', function(ev) { 

    if ((" " + ev.target.className + " ").indexOf(" dataCard ") < 0) return; 

    else manageMultitouch(ev, ev.target); }); 

    function manageMultitouch(ev, element) { 

     switch (ev.type) { 
      case 'touch': 
       last_scale = scale; 
           return; 
      case 'transform': 
       scale = Math.min(last_scale * ev.gesture.scale, 10); 
       break; 
      } 

      if(scale <= 0.5) $(element).hide('clip'); 

      if(scale > 1.0) $(element).addClass('focused'); 

      var transform = "translate(" + 0 + "px," + 0 + "px) " + "scale(" + 1 + "," + scale + ")"; 
      var style = element.style; 
      style.transform = transform; 
      style.oTransform = transform; 
      style.msTransform = transform; 
      style.mozTransform = transform; 
      style.webkitTransform = transform; 
    } 

回答

3

我曾在我的應用程序相同的問題,甚至包括觸摸一拳。我不得不做一個很好的研究,以找到停止jQuery UI拖動的問題。 發生的問題是在事件中設置了preventDefault(僅當包含錘子時),才能從jquery ui更改觸發器方法的結果。

那麼,讓我們回到一點: 你應該看到的第一種方法是_mouseMove(),它與mousemove事件相關聯。 僅當條件(this._mouseStart(this._mouseDownEvent, event) !== false)爲真時,纔會觸發拖動。

_mouseMove: function (event) { 
    // IE mouseup check - mouseup happened when mouse was out of window 
    if ($.ui.ie && (!document.documentMode || document.documentMode < 9) && !event.button) { 
     return this._mouseUp(event); 
    } 

    if (this._mouseStarted) { 
     this._mouseDrag(event); 
     return event.preventDefault(); 
    } 

    if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { 
     this._mouseStarted = 
      (this._mouseStart(this._mouseDownEvent, event) !== false); 
     (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); 
    } 

    return !this._mouseStarted; 
} 

下一個方法將創建助手(元素的克隆),在元素設置一些CSS和返回true(值我們預期),除非this._trigger("start", event)返回false。

_mouseStart: function(event) { 
    var o = this.options; 
    //Create and append the visible helper 
    this.helper = this._createHelper(event); 
    this.helper.addClass("ui-draggable-dragging"); 
    //Cache the helper size 
    this._cacheHelperProportions(); 
    //If ddmanager is used for droppables, set the global draggable 
    if($.ui.ddmanager) { 
     $.ui.ddmanager.current = this; 
    } 

    /* 
    * - Position generation - 
    * This block generates everything position related - it's the core of draggables. 
    */ 
    //Cache the margins of the original element 
    this._cacheMargins(); 
    //Store the helper's css position 
    this.cssPosition = this.helper.css("position"); 
    this.scrollParent = this.helper.scrollParent(); 
    this.offsetParent = this.helper.offsetParent(); 
    this.offsetParentCssPosition = this.offsetParent.css("position"); 
    //The element's absolute position on the page minus margins 
    this.offset = this.positionAbs = this.element.offset(); 
    this.offset = { 
     top: this.offset.top - this.margins.top, 
     left: this.offset.left - this.margins.left 
    }; 
    //Reset scroll cache 
    this.offset.scroll = false; 
    $.extend(this.offset, { 
     click: { //Where the click happened, relative to the element 
      left: event.pageX - this.offset.left, 
      top: event.pageY - this.offset.top 
     }, 
     parent: this._getParentOffset(), 
     relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper 
    }); 
    //Generate the original position 
    this.originalPosition = this.position = this._generatePosition(event); 
    this.originalPageX = event.pageX; 
    this.originalPageY = event.pageY; 
    //Adjust the mouse offset relative to the helper if "cursorAt" is supplied 
    (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); 
    //Set a containment if given in the options 
    this._setContainment(); 
    //Trigger event + callbacks 
    if(this._trigger("start", event) === false) { 
     this._clear(); 
     return false; 
    } 
    //Recache the helper size 
    this._cacheHelperProportions(); 
    //Prepare the droppable offsets 
    if ($.ui.ddmanager && !o.dropBehaviour) { 
     $.ui.ddmanager.prepareOffsets(this, event); 
    } 
    this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position 
    //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) 
    if ($.ui.ddmanager) { 
     $.ui.ddmanager.dragStart(this, event); 
    } 

    return true; 
} 

下面是第一個_trigger的調用,它來自於拖拽控件。

_trigger: function (type, event, ui) { 
     ui = ui || this._uiHash(); 
     $.ui.plugin.call(this, type, [event, ui]); 
     //The absolute position has to be recalculated after plugins 
     if(type === "drag") { 
      this.positionAbs = this._convertPositionTo("absolute"); 
     } 
     return $.Widget.prototype._trigger.call(this, type, event, ui); 
    } 

此時結果將調用另一個觸發方式(此時從$ .Widget),而這也正是我們的問題點。

_trigger: function (type, event, data) { 
    var prop, orig, 
     callback = this.options[type]; 

    data = data || {}; 
    event = $.Event(event); 
    event.type = (type === this.widgetEventPrefix ? 
     type : 
     this.widgetEventPrefix + type).toLowerCase(); 
    // the original event may come from any element 
    // so we need to reset the target on the new event 
    event.target = this.element[0]; 

    // copy original event properties over to the new event 
    orig = event.originalEvent; 
    if (orig) { 
     for (prop in orig) { 
      if (!(prop in event)) { 
       event[prop] = orig[prop]; 
      } 
     } 
    } 
    return !($.isFunction(callback) && callback.apply(this.element[0], [event].concat(data)) === false || event.isDefaultPrevented()); 
} 

return !($.isFunction(callback) && callback.apply(this.element[0], [event].concat(data)) === false || event.isDefaultPrevented()); 

我們的問題正是在這一行。更具體的||之前event.isDefaultPrevented()。 當包含錘子時,方法event.isDefaultPrevented()會生成真值,一旦返回之前值被拒絕,最終值將爲假。 (不包括錘子包括event.isDefaultPrevented()返回假如預期。) 備份在我們的_moseMouve(),而不是調用_mouseDrag()方法它會調用_mouseUp()。你可以看到它會解除事件並致電_mouseStop()

_mouseUp: function (event) { 
    $(document) 
     .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) 
     .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); 

    if (this._mouseStarted) { 
     this._mouseStarted = false; 

     if (event.target === this._mouseDownEvent.target) { 
      $.data(event.target, this.widgetName + ".preventClickEvent", true); 
     } 

     this._mouseStop(event); 
    } 

    return false; 
} 

如果通過AND(& &)改變OR(||)運算符,它會正常工作。當然,這不是一個小小的改變,我一直在測試它,直到現在我還沒有發現任何問題。行會是這樣:

return !($.isFunction(callback) && callback.apply(this.element[0], [event].concat(data)) === false && event.isDefaultPrevented()); 

正如我所說的,它不是100%安全的,但是到現在爲止我沒有找到一個理由讓||而不是& &。我會繼續測試幾天。 除此之外,我已經發送了一封電子郵件給jquery ui的首席開發人員詢問。

+0

難道開發商不斷回到你定了嗎? – rickdmer

+1

不幸的是,我發了兩封電子郵件,但我沒有得到任何回覆。不過,我保持這種改變,到目前爲止我沒有發現任何問題。 –

+0

Upvoted的精彩,努力和搖擺 –

0

我有同樣的問題,發現這個問題在github。使用它與同構的SmartClient

$(document).hammer().on('touch transform transformend', '#main', function() {...}); 
1

類似的問題對我來說:

使用事件代表團所示的方案爲我工作得很好。

我通過處理啓動事件和重置isDefaultPrevented假

$(element).draggable({ 
    start: function (event, ui) { 
    event.isDefaultPrevented = function() { return false; } 
    } 
}); 
+0

這對我有效,但不得不使用'拖'回調而不是啓動 – DaveB

相關問題