9

I am making a mobile website that uses JavaScript touch events. Things work fine in iOS Safari and Chrome for Android, but the stock Android Browser (version 4.1.2) is giving me trouble.

During a touch process, the touchstart and touchmove events are called as expected. However, one of the actions performed by the touchmove handler seems to trigger a premature touchcancel event. (I'm not sure whether this is significant, but the action that triggers the touchcancel is the modification of an SVG object's viewBox attribute.) If I comment out this action, the touch process proceeds normally (i.e., completion of touchmove through to touchend).

All of my touch handlers call the preventDefault() function, so the issue isn't the one that's described in this bug: https://code.google.com/p/android/issues/detail?id=19827.

I've read that there is a lot of inconsistency among browsers as to when touchcancel is called. The stock Android browser is the only one that is problematic for me.

Is there a workaround out there? For example, is there away I can completely disable the touchcancel event? Another idea I had was to have the touchcancel handler programmatically trigger another touchstart/touchmove event, but I didn't get very far with that. Any ideas would be appreciated.

David G.
  • 321
  • 3
  • 11
  • 3
    Argh! I think this problem has now migrated to Chrome Browser! It appeared in Version 28. See https://code.google.com/p/chromium/issues/detail?id=260732. – David G. Aug 01 '13 at 15:58
  • See also this post, which seems to be related: http://stackoverflow.com/questions/15944197/android-browser-touchcancel-being-fired-althought-touchmove-has-preventdefault – David G. Aug 01 '13 at 16:00
  • 2
    I'm experiencing this issue in Chrome Browser now, interfering with using Hammer.js. Anyone know how to get around this? – acjay Jan 14 '14 at 18:06
  • Complain here http://code.google.com/p/chromium/issues/detail?id=372357 – Old fart Aug 26 '14 at 00:53
  • For future reference, the answer here works perfectly: http://stackoverflow.com/questions/10367854/html5-android-touchcancel – Sam P Jul 24 '15 at 20:26

3 Answers3

4

I know it's a bit late but if someonee else is facing this issue, here's a small jQuery extension that explains how to deal with pointercancel and touchcancel events.

Basically, if you switch to pointer events you will be able to prevent pointercancel by simply using the touch-action CSS property with a value of none, as long as the browser has both features correctly implemented. (Android 5+, Chrome 55+, IE11, Edge, etc)

If you really must use the legacy touch events instead, you'll have to implement event.preventDefault() in your touchmove events and this will prevent touchcancel from firing, but it will also disable entirely the browser handling of any default action like a pan or click.

As a final note, I wouldn't use touch events + touch-action CSS rules because touch-action was only recently added, at the same that that Pointer Events. So while that combination may work in newer browsers, it will most certainly fail in older ones (by triggering touchcancel event unexpectedly).

Check the README from the jQuery extension I posted because it explains the implications of using either TouchEvent and PointerEvent interfaces.

andreszs
  • 2,589
  • 2
  • 22
  • 28
2

If you are useing hammer.js, you can disable pointer-events (which cause problems like this), by adding: delete window.PointerEvent; in your index.html PRIOR to loading hammer.js, and it will ignore those events.
You can also set SUPPORT_POINTER_EVENTS = false; (line 384 of v2.0.8) to do the same thing. Ideally the devs would add the ability to turn this off, but so goes the open source dilemma...

GrumpyGary
  • 111
  • 5
  • Awesome! Thanks! I am fighting with the Chrome (Android) touchcancel behaviour since days and this is the first solution that really solved my issues with hammer.js. – horace Feb 17 '18 at 21:46
  • are you kidding me!? I can't believe this worked. How insane! I have spent three days trying to troubleshoot why my UI was horked and this simple k̶l̶u̶d̶g̶e̶ fix solved it? wow.... just.... wow.... – Michael Feb 20 '18 at 22:04
0

I think touchcansel is special event that triggers when user touched button in specific behavior.

Ex. User touch button, but didn't removed his finger from display on exactly that button, instead of this he could move it a bit to the left, and end his action there. In that case touchcancel would appear.

So if you don't want that action to fire, i think you have to remove all handlers that connected with that action in android browser.

$('selector').off('touchcancel'), of if it's delefated $('parent').undelegate('touchcancel','selector')

I don't think that there is problem with e.preventDefault(). Only may be if you click on a link, and page starts to reload. May be page is reloaded when you click on button? and you wait for some actions after page reloaded, you actually may not understand, that it happend.

Rantiev
  • 1,869
  • 1
  • 22
  • 46
  • [Touchcancel](https://developer.mozilla.org/en-US/docs/Web/Events/touchcancel) will be inevitably fired by the browser, and trying to cancel or preventDefault inside it won't work as intended. – andreszs Oct 06 '17 at 02:50