Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Event bubbling issue with swipe gesture #6262
I've posted this issue on Stack Overflow but it's not getting much traction there. For all I can tell, this is either some weird edge case of how the swipe gesture is implemented or a bug in event bubbling.
What it boils down to the following:
But it appears that the swipe gesture is still bubbling up despite my request for it not to.
I tried my hand at creating a jsbin demonstrating the problem: http://jsbin.com/ofuhaw/113/
I was having trouble using an in-page selector to show the current count so I just went with console.log instead.
Just shrink your browser width so that the tab bar gets a scrollbar, pop open your console, and do swipes over both the page (below the
For contrast, here's a duplicate of that jsbin, with the swipe gestures completely commented out: http://jsbin.com/ofuhaw/115
"swiping" over the tabs scrolls them horizontally. (I'm having a lot of issues with jsbin; one of which being that this seems to only scroll the first time, but take my word for it, this code outside of jsbin does scroll just fine with swipe gestures removed)
Here's a jsFiddle that demonstrates how it should, in theory, work. This is the same HTML and CSS as my JSBin's above, but with absolutely no JS included other than the libraries.
You can open that up on a mobile device, then pinch-to-zoom in so that the tabs are scrollable, and swipe back and forth across them. This is the behavior that is obstructed by using the swipe gesture.
I ran into a problem with my events propagating as well on swipe events. I believe this is a bug introduced into the jquerymobile 1.4 release. I've tested the code with jquerymobile 1.3.2 and I get my events to stop propagating. On 1.4 they do not. Here are two fiddles that show the behavior.
http://jsfiddle.net/ta3gz/1/ - jQuery Mobile 1.3.2 which stops the bubbling
http://jsfiddle.net/nP5Z8/ - jQuery Mobile 1.4.0 which does not stop the bubbling.
I don't have a lot of cycles to debug this but I'll try looking at the unminified version of 1.4 and try to see what's going on.
I have debugged it.
The fundamental problem is this: If you attach a swipe handler to an element and you attach another swipe handler to a parent of that element, then two swipe events will be generated for every mouse gesture. That's because mouse events bubble, and so a sequence of mouse events will be processed by the swipe calculator attached to the element, and the same sequence of mouse events will be processed again by the swipe calculator attached to the parent.
In 1.3.2, we were triggering swipe on the element from which it originated and we were allowing it to bubble. Thus, both swipe events were being triggered on the element that received the original mousedown, so they were both getting passed to the handler which calls stopPropagation, so both events were prevented from bubbling.
In 1.4.0, we trigger swipe on the element to which the swipe handler is attached, not on the element that received the original mousedown and we're not allowing the swipe event to bubble. Thus, only one swipe event is being received by the handler which calls stopPropagation, because the other swipe event originates "above its head", at the parent, so it never gets a chance to call stopPropagation on it. The fact that the parent receives a swipe event with a non-prevented default is not due to the inner swipe event bubbling (because we don't allow that anymore), but because it is receiving a swipe event that was generated especially for it.
The correct solution IMO is to use a sequence of mouse events for the generation of at most one swipe event on the innermost element, and to allow that swipe event to bubble. What this means is that we have to set a global flag indicating that a swipe calculation is already in progress, so only the first swipe calculator will actually do any calculating, and all other swipe calculators will bail.