diff --git a/src/effects.js b/src/effects.js index 0469eefb6..af61de705 100644 --- a/src/effects.js +++ b/src/effects.js @@ -71,6 +71,18 @@ var } ] }; +function raf() { + if ( timerId ) { + window.requestAnimationFrame( raf ); + jQuery.fx.tick(); + } +} + +// 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() { @@ -460,6 +472,9 @@ 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() @@ -468,6 +483,10 @@ 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() { @@ -636,7 +655,12 @@ jQuery.fx.interval = 13; jQuery.fx.start = function() { if ( !timerId ) { - timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + if ( window.requestAnimationFrame ) { + timerId = true; + window.requestAnimationFrame( raf ); + } else { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } } }; diff --git a/test/unit/effects.js b/test/unit/effects.js index 9b4c4d5c1..30d58ccd3 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -5,8 +5,11 @@ if ( !jQuery.fx ) { return; } +var oldRaf = window.requestAnimationFrame; + module("effects", { setup: function() { + window.requestAnimationFrame = null; this.clock = sinon.useFakeTimers( 505877050 ); this._oldInterval = jQuery.fx.interval; jQuery.fx.interval = 10; @@ -15,6 +18,7 @@ module("effects", { this.clock.restore(); jQuery.fx.stop(); jQuery.fx.interval = this._oldInterval; + window.requestAnimationFrame = oldRaf; return moduleTeardown.apply( this, arguments ); } });