January 18, 2011

Android: touchmove event bug

touchmove events in Android web browsers have a really serious bug. If you don't include the following code, the touchmove event will fire once, but not again until you're done moving your touch, which utterly kills the usefulness of the touchmove event. It's a weird one, and may very well break more advanced touch logic that works on iOS. But if you preventDefault() on the touchstart event, your touchmove will function as expected.
element.addEventListener( "touchstart", function(e){ onStart(e); }, false );
function onStart ( touchEvent ) {
  if( navigator.userAgent.match(/Android/i) ) {
    touchEvent.preventDefault();
  }
}
This bug is documented here:
http://code.google.com/p/android/issues/detail?id=5491

and is probably not entirely unrelated to my previous post about weird Android Touch event behavior:
http://uihacker.blogspot.com/2010/10/android-bug-miss-drag-as-we-are-waiting.html

7 comments:

  1. thanks a lot, used this code now, it works well.

    ReplyDelete
  2. If it's useful for someone...
    Samsung galaxy Tab GT-P3100 with Android 4.0.4
    has a lot of problems in Phonegap...

    -Slide transitions blanking...
    -Touch events delays (worst than ever) with the message:
    NO_FAST_DRAW=false
    V/webview(24354): singleCursorHandlerTouchEvent
    getEditableSupport FASLE
    There is no way to prevent the delays, nor with event.preventdefault , NOTHING TO DO....

    The same application, exactly the same, the same device, but wiith Android 4.0.3, WORKS PERFECTLY!!!

    So, avoid upgrading Android version!
    Waiting to Jelly Bean to make the application working (HOPE FOR IT)
    or else.....







    ReplyDelete
  3. Thanks for this tip - I was using slide gestures to transition between pages iBooks style - where as you swipe the page follows your finger and the next one slides in a bit and depending on how far you drag it either continues slide to next page or snaps back. Couldn't figure out why it was failing so completely on Android - this totally fixed it for me.

    Obvious caveat is that if you still need to have the native scroll work - eg you want to use your touchmove event on horizontal swipe but you still have scrolling content vertically, you'll have to come up with a solution for that. An easy one would be to use a container div and stopping event propagation, but I'm sure there are other ways.

    ReplyDelete
  4. with out preventDefault shim : https://github.com/TNT-RoX/android-swipe-shim

    ReplyDelete
  5. Shim for this bug at https://github.com/TNT-RoX/android-swipe-shim

    ReplyDelete