Javascript – Understanding touch events

javascriptmobiletouch

I'm trying to make some of my libraries work with touch devices, but I'm having a hard time trying to figure out how they're supported and how they work.

Basically, there are 5 touch events, but it seems there's consensus among mobile browsers only on the touchstart event (duh). I've created a fiddle as a test case.

I've tested this on my Galaxy Note with Android 4 on board, but you can check the link with a desktop browser too.

The goal is to try to figure out how to handle taps, double taps and long taps. Nothing fancy.

Basically, this is what happens:

The Android stock browser doesn't fire touch events. It just tries to emulate mouse clicks with taps, firing mousedown, mouseup and click events consecutively, but double taps just zoom in and out tha page.

Chrome for Android fires the touchstart event when the finger touches the screen. If it's released soon enough, it fires then mousedown, mouseup, touchend and finally click events.

In case of long tap, after about half a second it fires mousedown and mouseup, and touchend when the finger is lifted, with no click event at the end.

If you move your finger, it fires a touchmove event a couple of times, then it fires a touchcancel event, and nothing happens afterwards, not even a touchend event when lifting the finger.

A double tap triggers the zoom in/out features, but event-wise it fires the combo touchstarttouchevent twice, with no mouse events fired.

Firefox for Android correctly fires the touchstart event, and in case of short tap fires mousedown, mouseup, touchend and click afterwards.

In case of long tap, it fires mousedown, mouseup and finally touchend events. It's the same of Chrome for these things.

But if you move your finger, if fires touchmove continously (as one may expect) but it doesn not fire the touchleave event when the finger leaves the element with the event listener, and doesn't fire the touchcancel event when the finger gets out of the browser viewport.

For double taps, it behaves just like Chrome.

Opera Mobile does the same thing of Chrome and Firefox for a short tap, but in case of long press activates some sort of sharing feature that I really want to disable. If you move your finger, or double tap, it behaves just like Firefox.

Chrome beta does the usual for short taps, but in case of long taps it doesn't fire the mouseup event anymore, just touchstart, then mousedown after half a second, then touchend when the finger is lifted. When the finger is moved, now it behaves like Firefox and Opera Mobile.

In case of double taps, it doesn't fire touch events when zooming out, but only when zooming in.

Chrome beta shows the oddest behaviour, but I can't really complain since it's a beta.

The question is: is there a simple and way to try to detect short taps, long taps and double taps in the most common browsers of touch devices?

Too bad I can't test it on iOS devices with Safari, or IE for Windows Phone 7/Phone 8/RT, but if some of you can, your feedback would be very appreciated.

Best Solution

If you haven't already, I would suggest reading the source code for Hammer.js

https://github.com/hammerjs/hammer.js/blob/master/hammer.js

Between comments and code it's about 1400 lines, there is great documentation and the code is easy to understand.

You can see how the author has chosen to solve a lot of the common touch events:

hold, tap, doubletap, drag, dragstart, dragend, dragup, dragdown, dragleft, dragright, swipe, swipeup, swipedown, swipeleft, swiperight, transform, transformstart, transformend, rotate, pinch, pinchin, pinchout, touch (gesture detection starts), release (gesture detection ends)

I think after reading the source code you will have much better understanding of how touch events work and how to identify which events the browser is capable of handling.

http://eightmedia.github.io/hammer.js/

Related Question