(Everybody reading this blog is smarter than me, so even though this is probably common knowledge Iâm going to write it down so I can look back next time Iâm dealing with fishy touch events.)
We had an interesting issue get reported on webcompat.com, âIssue 171: time.com - Clicking on âTapâ doesnât toggle menuâ that was only affecting Firefox Mobile. Essentially, tapping on a little ârail-handleâ to slide in some side content would result in the content sliding in then immediately sliding out.
Lucky for me, the site isnât that complicatedâitâs your run-of-the-mill Backbone.js app with obligatory canât-read-anything-until-you-dismiss-the-in-your-face-underwear advertising.
The listeners for the ârail handleâ are set up here:
this.$notHeader.find(".rail-handle").on("touchend click", function(_this) {
return function() {
_this.toggle_left_rail()
}
...
toggle_left_rail()
sets some classes on some parent elements which transitions the content out. I think. It doesnât actually matter how the handle and articles move outâjust that they do.
I eventually got the issue reduced down to https://miketaylr.com/bzla/wc-171-2.html. If you open that up on an Android device with Firefox Mobile and Chrome you can see the difference in behavior.
The actual bug here is Firefox Mobile dispatches the click event on the original target while Chrome (and iOS and Firefox OS and probably whatever wearable-with-a-browser is currently strapped to your body) will dipatch the event to the original location of the touchend
event. In my test case this is probably <body>
, in time.com this is probably <div class="left-rail>
. So Firefox for Android ends up calling toggle_left_rail()
twice, while other browsers only call it once as intended.
I filed a BugZilla issue on behalf of the original webcompat.com reporter. Feel free to follow that link if the internal details of how Firefox OS gets this right while Fennec doesnât (for now) interests you.
And naturally the spec says,
If the user agent intreprets a sequence of touch events as a click, then it should dispatch mousemove, mousedown, mouseup, and click events (in that order) at the location of the touchend event for the corresponding touch input. If the contents of the document have changed during processing of the touch events, then the user agent may dispatch the mouse events to a different target than the touch events.
So yeah. You all already knew that a synthetic event will be dispatched on whatever target is at the location of the originating touch event. I learned the slow way. Now letâs get back to surfing underwear ad interlaced journalism.