]> source.dussan.org Git - jquery.git/commitdiff
Effects: Improve raf logic
authorOleg Gaidarenko <markelog@gmail.com>
Mon, 12 May 2014 17:53:40 +0000 (21:53 +0400)
committerOleg Gaidarenko <markelog@gmail.com>
Sun, 15 Jun 2014 23:08:46 +0000 (03:08 +0400)
* Make animation behave as if jQuery.fx.off = true if document is hidden

* Use cancelAnimationFrame in jQuery.fx.stop

Closes gh-1578

src/effects.js
test/unit/effects.js

index 1ece6f49d76260b27eb396e4b2ce967095634430..f5361165ba81655dc2132b8b136e3ed4e76c966e 100644 (file)
@@ -78,11 +78,6 @@ function raf() {
        }
 }
 
-// Will get false negative for old browsers which is okay
-function isDocumentHidden() {
-       return "hidden" in document && document.hidden;
-}
-
 // Animations created synchronously will run synchronously
 function createFxNow() {
        setTimeout(function() {
@@ -438,8 +433,15 @@ jQuery.speed = function( speed, easing, fn ) {
                easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
        };
 
-       opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
-               opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+       // Go to the end state if fx are off or if document is hidden
+       if ( jQuery.fx.off || document.hidden ) {
+               opt.duration = 0;
+
+       } else {
+               opt.duration = typeof opt.duration === "number" ?
+                       opt.duration : opt.duration in jQuery.fx.speeds ?
+                               jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+       }
 
        // Normalize opt.queue - true/undefined/null -> "fx"
        if ( opt.queue == null || opt.queue === true ) {
@@ -464,9 +466,6 @@ jQuery.speed = function( speed, easing, fn ) {
 
 jQuery.fn.extend({
        fadeTo: function( speed, to, easing, callback ) {
-               if ( isDocumentHidden() ) {
-                       return this;
-               }
 
                // Show any hidden elements after setting opacity to 0
                return this.filter( isHidden ).css( "opacity", 0 ).show()
@@ -475,10 +474,6 @@ jQuery.fn.extend({
                        .end().animate({ opacity: to }, speed, easing, callback );
        },
        animate: function( prop, speed, easing, callback ) {
-               if ( isDocumentHidden() ) {
-                       return this;
-               }
-
                var empty = jQuery.isEmptyObject( prop ),
                        optall = jQuery.speed( speed, easing, callback ),
                        doAnimation = function() {
@@ -646,17 +641,19 @@ jQuery.fx.timer = function( timer ) {
 jQuery.fx.interval = 13;
 jQuery.fx.start = function() {
        if ( !timerId ) {
-               if ( window.requestAnimationFrame ) {
-                       timerId = true;
-                       window.requestAnimationFrame( raf );
-               } else {
-                       timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
-               }
+               timerId = window.requestAnimationFrame ?
+                       window.requestAnimationFrame( raf ) :
+                       setInterval( jQuery.fx.tick, jQuery.fx.interval );
        }
 };
 
 jQuery.fx.stop = function() {
-       clearInterval( timerId );
+       if ( window.cancelAnimationFrame ) {
+               window.cancelAnimationFrame( timerId );
+       } else {
+               clearInterval( timerId );
+       }
+
        timerId = null;
 };
 
index 91e622450a12d40fec030cfedcbdf37a503335a7..c49ea9e63f5eaf6acab88328ab00509760146f41 100644 (file)
@@ -2183,4 +2183,32 @@ test( "Respect display value on inline elements (#14824)", 2, function() {
        clock.tick( 800 );
 });
 
+test( "Animation should go to its end state if document.hidden = true", 1, function() {
+       var height;
+       if ( Object.defineProperty ) {
+
+               // Can't rewrite document.hidden property if its host property
+               try {
+                       Object.defineProperty( document, "hidden", {
+                               get: function() {
+                                       return true;
+                               }
+                       });
+               } catch ( e ) {}
+       } else {
+               document.hidden = true;
+       }
+
+       if ( document.hidden ) {
+               height = jQuery( "#qunit-fixture" ).animate({ height: 500 } ).height();
+
+               equal( height, 500, "Animation should happen immediately if document.hidden = true" );
+               jQuery( document ).removeProp( "hidden" );
+
+       } else {
+               ok( true, "Can't run the test since we can't reproduce correct environment for it" );
+       }
+});
+
+
 })();