Understanding touch events
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 touchstart
- touchevent
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.
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/
There's a really excellent resource https://patrickhlauke.github.io/touch/tests/results/ that details the order of events across a staggering number of browsers. It also appears to be updated regularly (in September 2016, it was last updated August 2016).
The gist is, essentially everything triggers mouseover
and related events; most also trigger touch events, which usually complete (reach touchend
) before mouseover
and then continue to click
(unless a change to page content cancels this). Those awkward exceptions are thankfully relatively rare (3rd party android browsers and blackberry playbook).
That linked resource goes into an impressive level of detail, here's a sample of the first three of many, many operating system, device and browser tests:
To summarise some of the key points:
Mobile browsers
mouseover
on the first tap. Only some Windows Phone browsers trigger it on a second tap. click
. It doesn't specify which cancel click
if mouseover
changes the page (I believe most do) mouseover
after touchstart
and touchend
. This includes iOS7.1 Safari, stock Android, Chrome, Opera and Firefox for Android, and some (not all Windows phone browsers) mouseover
after touchstart
and touchend
. mouseover
between touchstart
and touchend
touchstart
or touchend
. Desktop browsers
touchstart
and touchend
followed by mouseover
. touchstart
and touchend
events. touchstart
and touchend
given the scarcity of Mac touchscreen interfaces. There's also an incredible amount of data on browsers combined with assistive technologies.
Here is my latest observation on touch and mouse events on Android 4.3
Opera, Firefox, and Chrome seem to have a standard behavior
On Swipe (touchstart-touchmove-touchend):
On Tap(touchstart-touchend):
Android default browser has some non-standard behaviors :
下一篇: 了解触摸事件