Refactored events and split out into a separate file.

This commit is contained in:
Scott González 2010-09-14 17:33:50 -04:00
parent 3ac820c671
commit 8acc5258a4
2 changed files with 149 additions and 101 deletions

146
js/jQuery.mobile.event.js Normal file
View file

@ -0,0 +1,146 @@
// add new event shortcuts
$.each( "touchstart touchmove touchend orientationchange tap taphold swipe swipeleft swiperight scrollstart scrollstop".split( " " ), function( i, name ) {
$.fn[ name ] = function( fn ) {
return fn ? this.bind( name, fn ) : this.trigger( name );
};
$.attrFn[ name ] = true;
});
var supportTouch = $.support.touch,
scrollEvent = supportTouch ? "touchmove" : "scroll",
touchStartEvent = supportTouch ? "touchstart" : "mousedown",
touchStopEvent = supportTouch ? "touchend" : "mouseup",
touchMoveEvent = supportTouch ? "touchmove" : "mousemove";
// also handles scrollstop
$.event.special.scrollstart = {
enabled: true,
setup: function() {
var thisObject = this,
$this = $( thisObject ),
timer;
function trigger( event, scrolling ) {
$this.data( "ui-scrolling", scrolling );
var originalType = event.type;
event.type = scrolling ? "scrollstart" : "scrollstop";
$.event.handle.call( thisObject, event );
event.type = originalType;
}
// iPhone triggers scroll after a small delay; use touchmove instead
$this.bind( scrollEvent, function( event ) {
if ( !$.event.special.scrollstart.enabled ) {
return;
}
if ( !$this.data( "ui-scrolling" ) ) {
trigger( event, true );
}
clearTimeout( timer );
timer = setTimeout(function() {
trigger( event, false );
}, 50 );
});
}
};
// also handles taphold
$.event.special.tap = {
setup: function() {
var thisObject = this,
$this = $( thisObject ),
originalType,
touching,
held,
moved,
timer;
$this
.bind( touchStartEvent, function( event ) {
held = false;
moved = false;
touching = true;
timer = setTimeout(function() {
if ( touching && !moved ) {
held = true;
originalType = event.type;
event.type = "taphold";
$.event.handle.call( thisObject, event );
event.type = originalType;
}
}, 300 );
event.preventDefault();
})
.bind( touchMoveEvent, function() {
moved = true;
})
.bind( touchStopEvent, function( event ) {
clearTimeout( timer );
touching = false;
if ( !held && !moved ) {
originalType = event.type;
event.type = "tap";
$.event.handle.call( thisObject, event );
event.type = originalType;
}
});
}
};
// also handles swipeleft, swiperight
$.event.special.swipe = {
setup: function() {
var thisObject = this,
$this = $( thisObject ),
start,
stop;
$this
.bind( touchStartEvent, function( event ) {
var data = event.originalEvent.touches ?
event.originalEvent.touches[ 0 ] :
event;
start = {
time: (new Date).getTime(),
coords: [ data.pageX, data.pageY ],
origin: $( event.target )
};
})
.bind( touchMoveEvent, function( event ) {
if ( !start ) {
return;
}
var data = event.originalEvent.touches ?
event.originalEvent.touches[ 0 ] :
event;
stop = {
time: (new Date).getTime(),
coords: [ data.pageX, data.pageY ]
};
// prevent scrolling
if ( Math.abs( start.coords[0] - stop.coords[0] ) > 10 ) {
event.preventDefault();
}
})
.bind( touchStopEvent, function( event ) {
if ( start && stop ) {
if ( stop.time - start.time < 1000 &&
Math.abs( start.coords[0] - stop.coords[0]) > 180 &&
Math.abs( start.coords[1] - stop.coords[1]) < 80 ) {
start.origin
.trigger( "swipe" )
.trigger( start.coords[0] > stop.coords[0] ? "swipeleft" : "swiperight" );
}
}
start = stop = undefined;
});
}
};

View file

@ -26,18 +26,7 @@
transitionDuration = 350,
orientation,
backBtnText = "Back",
prevUrl = location.hash,
//vars for custom event tracking
scrolling = false,
scrollListeningOn = true,
touching = false,
touchstartdata,
touchstopdata,
tapNotMoveTime = 75,
tapHoldTime = 300,
maxSwipeTime = 1000,
minSwipeXDistance = 180,
maxSwipeYtolerance = 80;
prevUrl = location.hash;
/*
add some core behavior,events
@ -75,101 +64,14 @@
//hide Address bar
function hideBrowserChrome(){
//kill addr bar
scrollListeningOn = false;
$.event.special.scrollstart.enabled = false;
window.scrollTo(0,0);
setTimeout(function(){
scrollListeningOn = true;
$.event.special.scrollstart.enabled = true;
}, 150);
}
//get vert scroll dist
$.scrollY = function(){
return $(window).scrollTop(); //always returns 0 WebOS!! HELP! http://jsbin.com/unufu3/5/edit
};
//add new event shortcuts
$.each( ("touchstart touchmove touchend orientationchange tap swipe swipeleft swiperight scrollstart scrollstop").split(" "), function( i, name ) {
// Handle event binding
$.fn[ name ] = function( fn ) {
return fn ? this.live( name, fn ) : this.trigger( name );
};
if ( $.attrFn ) {
$.attrFn[ name ] = true;
}
});
//detect and trigger some custom events (scrollstart,scrollstop,tap,taphold,swipe,swipeleft,swiperight)
$(document)
.scroll(function(e){
if(!scrollListeningOn){ return false; }
var prevscroll = $.scrollY();
function checkscrollstop(){
if(prevscroll === $.scrollY() && scrolling && scrollListeningOn){
$body.trigger('scrollstop');
scrolling = false;
}
}
setTimeout(checkscrollstop,50);
})
.bind( ($.support.touch ? 'touchmove' : 'scroll'), function(e){
if(!scrollListeningOn){ return false; }
//iPhone triggers scroll a tad late - touchmoved preferred
if(!scrolling){
scrolling = true;
$body.trigger('scrollstart'); //good place to trigger?
}
})
.bind( ($.support.touch ? 'touchstart' : 'mousedown'), function(e){
touching = true;
//make sure it's not a touchmove and still touching
function checktap(eType){
if(!scrolling && touching){
$(e.target).trigger(eType);
}
}
//tap / taphold detection timeouts (make sure it's not a touchmove & before firing)
setTimeout(checktap, tapNotMoveTime, ['tap']);
setTimeout(checktap, tapHoldTime, ['taphold']);
//cache data from touch start - for later use in swipe testing
var eScope = e.originalEvent.touches ? e.originalEvent.touches[0] : e;
touchstartdata = {
'time': (new Date).getTime(),
'coords': [eScope.pageX, eScope.pageY],
'origin': $(e.target)
};
})
.bind(($.support.touch ? 'touchmove' : 'mousemove'), function(e){
if(touchstartdata){
var eScope = e.originalEvent.touches ? e.originalEvent.touches[0] : e;
touchstopdata = {
'time': (new Date).getTime(),
'coords': [eScope.pageX, eScope.pageY]
};
//trying not to interfere with scrolling here...
//this may need to be expanded to any non-y movement...
if(Math.abs(touchstartdata.coords[0] - touchstopdata.coords[0]) > 10){
e.preventDefault();
}
}
})
.bind(($.support.touch ? 'touchend' : 'mouseup'), function(e){
touching = false;
if(touchstartdata && touchstopdata){
//detect whether a swipe occurred, trigger it
if( touchstopdata.time - touchstartdata.time < maxSwipeTime &&
Math.abs(touchstartdata.coords[0] - touchstopdata.coords[0]) > minSwipeXDistance &&
Math.abs(touchstartdata.coords[1] - touchstopdata.coords[1]) < maxSwipeYtolerance ){
touchstartdata.origin.trigger('swipe');
touchstartdata.origin.trigger( (touchstartdata.coords[0] > touchstopdata.coords[0] ? 'swipeleft' : 'swiperight'));
}
}
touchstartdata = touchstopdata = null;
});
//add orientation class on flip/resize. This should probably use special events. Also, any drawbacks to just using resize?
$window.bind( ($.support.orientation ? 'orientationchange' : 'resize'), updateOrientation);