Understanding touch events
Asked Answered
M

4

81

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.

Marcelina answered 23/1, 2013 at 18:31 Comment(1)
Have you tried Tocca.js? gianlucaguarini.github.io/Tocca.js It enables all the missing touch events on any kind of device and it's just about 1kbLoraineloralee
D
26

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/

Demos answered 6/9, 2013 at 18:34 Comment(1)
Interesting piece of code, seems quite complete and extensive. I might take some time analyzing it.Marcelina
T
9

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:

enter image description here

To summarise some of the key points:

Mobile browsers

  • All listed browsers trigger mouseover on the first tap. Only some Windows Phone browsers trigger it on a second tap.
  • All trigger click. It doesn't specify which cancel click if mouseover changes the page (I believe most do)
  • Most browsers trigger 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)
  • Several Windows Phone browsers (all Windows 8 / 8.1 and one version for 10) and several 3rd-party Android browsers (Dolphin, Maxathon, UC) trigger mouseover after touchstart and touchend.
  • Only Blackberry Playbook triggers mouseover between touchstart and touchend
  • Only Opera Mini and Puffin (3rd party Android browser) lack touchstart or touchend.

Desktop browsers

  • Reasonably up to date versions of desktop Chrome and Opera behave like their mobile counterparts, touchstart and touchend followed by mouseover.
  • Firefox and Microsoft browsers (IE <=11 and many versions of Edge) don't trigger any touchstart and touchend events.
  • No data on Macs, but presumably no Ma browsers support touchstart and touchend given the scarcity of Mac touchscreen interfaces.

There's also an incredible amount of data on browsers combined with assistive technologies.

Tolu answered 13/9, 2016 at 18:51 Comment(0)
A
3

Yes you can start a timer attouchstart and end it on touchend and make your choices from there.

Also you can make... let's say swipe, my triggering touchmove you can get the coordonates of the "finger" and see how much i traveled before touchend gets triggered.

I don't know if there's any simpler way rather than using a touch events library, but i suppose you could write one for simple 'tap', 'double tap', 'swipe' events pretty easily.

Arrhenius answered 23/1, 2013 at 18:34 Comment(5)
If you think about it, and consider the behaviour of the browsers above, you'll admit that's not easy at all. For example, if you touch an element, then move your finger outside the element and then lift the finger, that wouldn't be a valid "tap", but you can't detect it since touchleave is never fired.Marcelina
You make a good point, BUT; with proper coding, such us, capturing the element e.target (i believe) at touchstart, does it equal with the element on touchend? If no, then it's not a valid tap, it's a trap. I'm not saying coding a library would be easy, but it's not really "hard", i would rank it as "medium" + what's the fun if it's not challenging and making us return on stackoverflow xDArrhenius
Coding a library wouldn't be a problem for me, I find it challenging, satisfying and somewhat fun. But your comment just hints at a solution, but how do you build it? Where do you keep the informations about the touchstart event? What if a second touchstart event is fired meanwhile (multitouch display)? How do you handle long taps? Using setTimeout, but what if the finger leaves the element meanwhile? How do you detect it if no touch events are fired? And so on... I'll give a try of course, but I was hoping to find a deep analisys of touch events.Marcelina
You cant fire a second touchstart event without the touchend event being fired, hence you cant have two simoultneusly taps, so its no problem. You would keep the information in the variables and reset them at touchendArrhenius
That's incorrect, you can have a second touchstart before the first touchend occurs. Moreover, thinking about your answer again leads to the conclusion that it won't help, because the target property of the touchend event always equals the element in which the touch started, even when the finger was moved outside the element!Marcelina
O
3

Here is my latest observation on touch and mouse events on Android 4.3

Opera, Firefox, and Chrome seem to have a standard behavior

  1. On Swipe (touchstart-touchmove-touchend):

    1. No mouse event(exluding mouseover) fires.
    2. Mouseover fires only if touchstart and touchend occurs on the same element. (touchstart-touchmove-touchend-mouseover)
    3. If default is prevented on touchstart: the default swipe behavior does not work. no changes occur regarding mouse event firing.
  2. On Tap(touchstart-touchend):

    1. All mouse events mouseover-mousemove-mousedown-mouseup-click fire after a delay
    2. If default is prevented on touchstart: only mouseover fires.

Android default browser has some non-standard behaviors:

  1. Mouseover fires before touchstart which means mouseover always fires.
  2. All mouse events fire on Tap, even if the default is prevented on touchstart.
Overshoe answered 18/12, 2013 at 15:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.