I had the same problem in my application, even with the touch point enabled. I had to do some good research to find out what the problem with jquery ui overloading is. The emerging issue is the Default warning set in the event (only when the hammer is turned on), changing the result of the trigger method from jquery ui.
Ok, let's go back a bit: The first method you should see is _mouseMove() , associated with the mousemove event. Drag and drop will only be performed when the condition (this._mouseStart(this._mouseDownEvent, event) !== false) is true.
_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; }
The following method will create a helper (clone of the element), set some css in the element and return true (the expected value) if this._trigger("start", event) does not return false.
_mouseStart: function(event) { var o = this.options;
Below is the first trigger called, its view from the widget.
_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); }
At this point, the result will call another trigger method (this time from $ .Widget) and the point at which we have a problem.
_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());
Our problem is in this line. More specifically || before event.isDefaultPrevented() . When the hammer is turned on, the event.isDefaultPrevented() method returns true, after the value is rejected before returning, the final value will be false. (Without a hammer, the included event.isDefaultPrevented() returns false as expected.) After backing up our _moseMouve() , instead of calling the _mouseDrag() method, it will call _mouseUp() . U can see that it will cancel events and call _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; }
If you change the OR (||) operator with AND (& &), it will work fine. Of course, this is not a small change, I tested it, and until that moment I did not find any problems. The line will be like this:
return !($.isFunction(callback) && callback.apply(this.element[0], [event].concat(data)) === false && event.isDefaultPrevented());
As I said, it is not 100% safe, but so far I have not found a reason to save || instead of & &. I will check it for a few days. In addition, I already sent an email to the lead developer from jquery ui asking about it.