furf / jquery-ui-touch-punch

A duck punch for adding touch events to jQuery UI
http://touchpunch.furf.com/
3.51k stars 1.33k forks source link

Touch events doesn't works on Android 5.1.1 #259

Open ArMikael opened 8 years ago

ArMikael commented 8 years ago

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?

rob1256 commented 8 years ago

Also come across this issue using jQuery 'sortable' as well, haven't found a fix as of yet though.

frequeradio commented 8 years ago

Does not work on Android 6.0.1, on HTC one M9. Same issue as ArMikael

dosentier commented 8 years ago

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.

EikeKre commented 8 years ago

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

solution4you commented 8 years ago

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 !

EikeKre commented 8 years ago

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

ISSJS commented 8 years ago

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:

/*!

var mouseProto = $.ui.mouse.prototype, _mouseInit = mouseProto._mouseInit, _mouseDestroy = mouseProto._mouseDestroy, touchHandled, posX, posY;

/**

// 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');

};

/**

})(jQuery);

solution4you commented 8 years ago

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