From 8acc5258a417755825da00a482d583c43c20c53f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Scott=20Gonz=C3=A1lez?= Date: Tue, 14 Sep 2010 17:33:50 -0400 Subject: [PATCH] Refactored events and split out into a separate file. --- js/jQuery.mobile.event.js | 146 ++++++++++++++++++++++++++++++++++++++ js/jQuery.mobile.js | 104 +-------------------------- 2 files changed, 149 insertions(+), 101 deletions(-) create mode 100644 js/jQuery.mobile.event.js diff --git a/js/jQuery.mobile.event.js b/js/jQuery.mobile.event.js new file mode 100644 index 00000000..d7950fb5 --- /dev/null +++ b/js/jQuery.mobile.event.js @@ -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; + }); + } +}; diff --git a/js/jQuery.mobile.js b/js/jQuery.mobile.js index e26fa0bf..fe1e74f4 100644 --- a/js/jQuery.mobile.js +++ b/js/jQuery.mobile.js @@ -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);