Open ArMikael opened 8 years ago
Also come across this issue using jQuery 'sortable' as well, haven't found a fix as of yet though.
Does not work on Android 6.0.1, on HTC one M9. Same issue as ArMikael
Did you guys try out different smartphones and did it work on any of them? I noticed that timing really is crucial when it comes to the load order, especially making sure that JQuery UI actually is loaded before Touch Punch. Try putting them into the site's header to have a depending order here, when it works afterwards that should be the problem.
Here the same behavior. Works on desktop but not on Android Chrome and CM-Browser I have Android 5.1.1 on Galaxy S6 with Chrome 50.0.2661.89 CM 5.20.44
Hi,
I also had problem with some click event under Android and I think I found a fix for this. It seems to be related to a "false" mousemove event that prevent the click event to be launch in the touchEnd handler.
This is the fix :
...
var mouseProto = $.ui.mouse.prototype,
_mouseInit = mouseProto._mouseInit,
_mouseDestroy = mouseProto._mouseDestroy,
touchHandled, posX, posY
;
...
mouseProto._touchStart = function (event) {
... // Track movement to determine if interaction was a click self._touchMoved = false;
// Track element position to avoid "false" move
posX = event.originalEvent.changedTouches[0].screenX;
posY = event.originalEvent.changedTouches[0].screenY;
... }
mouseProto._touchMove = function (event) {
// Ignore event if not handled if (!touchHandled) { return; }
// Ignore if it's a "false" move (position not changed)
if ((posX==event.originalEvent.changedTouches[0].screenX) &&
(posY==event.originalEvent.changedTouches[0].screenY)) {
return;
}
...
};
Hope it helps !
This is almost the solution but for me this does not work precisely because there is no tolerance. The first saved posX is always a few pixels more/less than the screenX in the comparison.
This works for me:
// Track element position to avoid "false" move
posX = event.originalEvent.changedTouches[0].screenX.toFixed(0);
posY = event.originalEvent.changedTouches[0].screenY.toFixed(0);
// Ignore if it's a "false" move (position not changed)
var x = event.originalEvent.changedTouches[0].screenX.toFixed(0);
var y = event.originalEvent.changedTouches[0].screenY.toFixed(0);
// Ignore if it's a "false" move (position not changed)
if (Math.abs(posX - x) <= 2 && Math.abs(posY - y) <= 2) {
return;
}
Thanks @solution4you
Hi there, this works (pity) not on my IPad and IPhone6 (iOS)
can somebody please post the complete code wich works on all touchable devices? ( i will love you for solution!)
my code:
/*!
jquery.ui.mouse.js */ (function ($) {
// Detect touch support $.support.touch = 'ontouchend' in document;
// Ignore browsers without touch support if (!$.support.touch) { return; }
var mouseProto = $.ui.mouse.prototype, _mouseInit = mouseProto._mouseInit, _mouseDestroy = mouseProto._mouseDestroy, touchHandled, posX, posY;
/**
@param {String} simulatedType The corresponding mouse event */ function simulateMouseEvent (event, simulatedType) {
// Ignore multi-touch events if (event.originalEvent.touches.length > 1) { return; }
event.preventDefault();
var touch = event.originalEvent.changedTouches[0], simulatedEvent = document.createEvent('MouseEvents');
// Initialize the simulated mouse event using the touch event's coordinates
simulatedEvent.initMouseEvent(
simulatedType, // type
true, // bubbles
true, // cancelable
window, // view
1, // detail
touch.screenX, // screenX
touch.screenY, // screenY
touch.clientX, // clientX
touch.clientY, // clientY
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
0, // button
null // relatedTarget
);
// Dispatch the simulated event to the target element event.target.dispatchEvent(simulatedEvent); }
/**
@param {Object} event The widget element's touchstart event */ mouseProto._touchStart = function (event) {
var self = this;
// Ignore the event if another widget is already being handled if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) { return; }
// Set the flag to prevent other widgets from inheriting the touch event touchHandled = true;
// Track movement to determine if interaction was a click self._touchMoved = false;
// Track element position to avoid "false" move posX = event.originalEvent.changedTouches[0].screenX.toFixed(0); posY = event.originalEvent.changedTouches[0].screenY.toFixed(0);
// Simulate the mouseover event simulateMouseEvent(event, 'mouseover');
// Simulate the mousemove event simulateMouseEvent(event, 'mousemove');
// Simulate the mousedown event simulateMouseEvent(event, 'mousedown'); };
/**
// Ignore event if not handled if (!touchHandled) { return; }
// Ignore if it's a "false" move (position not changed) var x = event.originalEvent.changedTouches[0].screenX.toFixed(0); var y = event.originalEvent.changedTouches[0].screenY.toFixed(0); // Ignore if it's a "false" move (position not changed) if (Math.abs(posX - x) <= 2 && Math.abs(posY - y) <= 2) { return; }
// Interaction was not a click
this._touchMoved = true;
// Simulate the mousemove event
simulateMouseEvent(event, 'mousemove');
};
/**
@param {Object} event The document's touchend event */ mouseProto._touchEnd = function (event) {
// Ignore event if not handled if (!touchHandled) { return; }
// Simulate the mouseup event simulateMouseEvent(event, 'mouseup');
// Simulate the mouseout event simulateMouseEvent(event, 'mouseout');
// If the touch interaction did not move, it should trigger a click if (!this._touchMoved) {
// Simulate the click event
simulateMouseEvent(event, 'click');
}
// Unset the flag to allow other widgets to inherit the touch event touchHandled = false;
};
/**
original mouse event handling methods. */ mouseProto._mouseInit = function () {
var self = this;
// Delegate the touch handlers to the widget's element self.element.bind({ touchstart: $.proxy(self, '_touchStart'), touchmove: $.proxy(self, '_touchMove'), touchend: $.proxy(self, '_touchEnd') });
// Call the original $.ui.mouse init method _mouseInit.call(self); };
/**
Remove the touch event handlers */ mouseProto._mouseDestroy = function () {
var self = this;
// Delegate the touch handlers to the widget's element self.element.unbind({ touchstart: $.proxy(self, '_touchStart'), touchmove: $.proxy(self, '_touchMove'), touchend: $.proxy(self, '_touchEnd') });
// Call the original $.ui.mouse destroy method _mouseDestroy.call(self); };
})(jQuery);
Put some alert or console commands to try to understand what happen with this._touchMoved The problem is related to the fact that the click event is not fired in the touchend event
// If the touch interaction did not move, it should trigger a click if (!this._touchMoved) {
// Simulate the click event simulateMouseEvent(event, 'click');
}
You have to understand why this part of code is not executed
We've used this great library in one of our projects and now found that the click event doesn't work on Android 5.1.1 (lmy47v) on Nexus 10. Checked it also on the jquery-ui-touch-punch codepen demo here and encountered the same issue there. Click on draggable items doesn't work.
Guys, maybe you have some ideas what could be the reason and where to look for the reason?