Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added new throttledresize special event, including unit tests. This e…

…vent prevents browsers from running continuous callbacks on resize, which we use internally for orientationchange in browsers like IE. It still ensures that a held event will execute after the timeout, so logic that depends on the final conditions after a resize is complete will still execute properly. This improves performance noticeably, and... Fixes #1496. Fixes #1848. Fixes #1422.

The included tests pass most of the time, but they need improvements as they will occasionally fail due to faulty timing in the tests themselves, as far as I can tell (the code tests out fine in our functional demos).
  • Loading branch information...
commit 8c6164dbf0a692f331f4c48eb99dc51bad5252c1 1 parent c4491d2
scottjehl authored
Showing with 104 additions and 3 deletions.
  1. +38 −3 js/jquery.mobile.event.js
  2. +66 −0 tests/unit/event/event_core.js
View
41 js/jquery.mobile.event.js
@@ -7,7 +7,7 @@
(function($, undefined ) {
// add new event shortcuts
-$.each( "touchstart touchmove touchend orientationchange tap taphold swipe swipeleft swiperight scrollstart scrollstop".split( " " ), function( i, name ) {
+$.each( "touchstart touchmove touchend orientationchange throttledresize tap taphold swipe swipeleft swiperight scrollstart scrollstop".split( " " ), function( i, name ) {
$.fn[ name ] = function( fn ) {
return fn ? this.bind( name, fn ) : this.trigger( name );
};
@@ -182,7 +182,7 @@ $.event.special.swipe = {
// Because the orientationchange event doesn't exist, simulate the
// event by testing window dimensions on resize.
- win.bind( "resize", handler );
+ win.bind( "throttledresize", handler );
},
teardown: function(){
// If the event is not supported natively, return false so that
@@ -191,7 +191,7 @@ $.event.special.swipe = {
// Because the orientationchange event doesn't exist, unbind the
// resize event handler.
- win.unbind( "resize", handler );
+ win.unbind( "throttledresize", handler );
},
add: function( handleObj ) {
// Save a reference to the bound event handler.
@@ -229,6 +229,41 @@ $.event.special.swipe = {
})(jQuery);
+
+// throttled resize event
+(function(){
+ $.event.special.throttledresize = {
+ setup: function() {
+ $( this ).bind( "resize", handler );
+ },
+ teardown: function(){
+ $( this ).unbind( "resize", handler );
+ }
+ };
+
+ var throttle = 250,
+ handler = function(){
+ curr = ( new Date() ).getTime();
+ diff = curr - lastCall;
+ if( diff >= throttle ){
+ lastCall = curr;
+ $( this ).trigger( "throttledresize" );
+ }
+ else{
+ if( heldCall ){
+ clearTimeout( heldCall );
+ }
+ //promise a held call will still execute
+ heldCall = setTimeout( handler, throttle - diff );
+ }
+ },
+ lastCall = 0,
+ heldCall,
+ curr,
+ diff;
+})();
+
+
$.each({
scrollstop: "scrollstart",
taphold: "tap",
View
66 tests/unit/event/event_core.js
@@ -69,6 +69,8 @@
$('#qunit-fixture').touchstart();
stop();
});
+
+
test( "defining event functions sets the attrFn to true", function(){
$.each(events, function(i, name){
@@ -378,4 +380,68 @@
returnValue: undefined //NOTE result of unbind function call
});
});
+
+ /* The following 4 tests are async so that the throttled event triggers don't interfere with subsequent tests */
+
+ asyncTest( "throttledresize event proxies resize events", function(){
+ var called = false;
+ $(window).bind( "throttledresize", function(){
+ called = true;
+ });
+
+ $(window).trigger("resize");
+
+ setTimeout(function(){
+ ok( called );
+ $(window).unbind( "throttledresize" );
+ setTimeout(start, 500);
+ }, 500);
+ });
+
+ asyncTest( "throttledresize event prevents resize events from firing more frequently than 250ms", function(){
+ var called = 0;
+ $(window).bind( "throttledresize", function(){
+ called ++;
+ });
+
+ $(window).trigger( "resize" ).trigger( "resize" );
+
+ setTimeout(function(){
+ ok( called == 1 );
+ $(window).unbind( "throttledresize" );
+ setTimeout(start, 500);
+ }, 100);
+ });
+
+ asyncTest( "throttledresize event promises that a held call will execute after trottled timeout", function(){
+ var called = 0;
+
+ $(window).bind( "throttledresize", function(){
+ called ++;
+ });
+
+ $(window).trigger( "resize" ).trigger( "resize" );
+ setTimeout(function(){
+ ok( called == 2 );
+ $(window).unbind( "throttledresize" );
+ setTimeout(start, 500);
+ }, 500);
+ });
+
+ asyncTest( "throttledresize event promises that a held call will execute only once after trottled timeout", function(){
+ var called = 0;
+
+ $(window).bind( "throttledresize", function(){
+ called ++;
+ });
+
+ $(window).trigger( "resize" ).trigger( "resize" ).trigger( "resize" );
+
+ setTimeout(function(){
+ ok( called == 2 );
+ $(window).unbind( "throttledresize" );
+ setTimeout(start, 500);
+ }, 500);
+ });
+
})(jQuery);
Please sign in to comment.
Something went wrong with that request. Please try again.