Skip to content
This repository has been archived by the owner on Oct 8, 2021. It is now read-only.

Commit

Permalink
Swipe event: Trigger only one event per mouse sequence and let it bubble
Browse files Browse the repository at this point in the history
The element to which a mousedown handler is attached by the swipe setup() code
takes ownership of the next swipe event. This means that, if the same mousedown
event triggers other swipe setup() -attached mousedown handlers as it bubbles,
the subsequent ones will bail. Thus, if a swipe event results from the mousedown
then such a swipe event will be triggered on the deepest element with an
attached swipe handler, and it will be allowed to bubble from there. This
provides the tools that developers can use to avoid scenarios such as the one
mentioned in the referenced issue.

Fixes gh-6262
  • Loading branch information
Gabriel Schulhof committed Jan 15, 2014
1 parent abc9754 commit 0906f75
Showing 1 changed file with 28 additions and 5 deletions.
33 changes: 28 additions & 5 deletions js/events/touch.js
Expand Up @@ -30,10 +30,14 @@ define( [ "jquery", "../jquery.mobile.vmouse", "../jquery.mobile.support.touch"
}
});

function triggerCustomEvent( obj, eventType, event ) {
function triggerCustomEvent( obj, eventType, event, bubble ) {
var originalType = event.type;
event.type = eventType;
$.event.dispatch.call( obj, event );
if ( bubble ) {
$.event.trigger( event, undefined, obj );
} else {
$.event.dispatch.call( obj, event );
}
event.type = originalType;
}

Expand Down Expand Up @@ -170,19 +174,30 @@ define( [ "jquery", "../jquery.mobile.vmouse", "../jquery.mobile.support.touch"
Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {
var direction = start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight";

triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop }) );
triggerCustomEvent( thisObject, direction,$.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ) );
triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop }), true );
triggerCustomEvent( thisObject, direction,$.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true );
return true;
}
return false;

},

// This serves as a flag to ensure that at most one swipe event event is
// in work at any given time
context: null,

setup: function() {
var thisObject = this,
$this = $( thisObject );

$this.bind( touchStartEvent, function( event ) {

// Bail if we're already working on a swipe event
if ( $.event.special.swipe.context ) {
return;
}
$.event.special.swipe.context = thisObject;

var stop,
start = $.event.special.swipe.start( event ),
origTarget = event.target,
Expand All @@ -196,16 +211,24 @@ define( [ "jquery", "../jquery.mobile.vmouse", "../jquery.mobile.support.touch"
stop = $.event.special.swipe.stop( event );
if ( !emitted ) {
emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget );
if ( emitted ) {

// Reset the context to make way for the next swipe event
$.event.special.swipe.context = null;
}
}
// prevent scrolling
if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
event.preventDefault();
}
}

$this.bind( touchMoveEvent, moveHandler )
$document.bind( touchMoveEvent, moveHandler )
.one( touchStopEvent, function() {
emitted = true;

// Reset the context to make way for the next swipe event
$.event.special.swipe.context = null;
$this.unbind( touchMoveEvent, moveHandler );
});
});
Expand Down

0 comments on commit 0906f75

Please sign in to comment.