From 06a45406966ee8cde31c4f128d7ee68d727880c1 Mon Sep 17 00:00:00 2001 From: Oleg Gaidarenko Date: Mon, 16 Jun 2014 02:43:31 +0400 Subject: [PATCH] Effects: Reintroduce use of requestAnimationFrame Same as before, just use don't use prefixes, since they pretty match useless now and use page visibility API to determine if animation should start. Also null the requestAnimationFrame attribute in window for tests since sinon does not provide fake method for it. Fixes #15147 Ref 72119e0023dcc0d9807caf6d988598b74abdc937 --- src/effects.js | 26 +++++++++++++++++++++++++- test/unit/effects.js | 4 ++++ 2 files changed, 29 insertions(+), 1 deletion(-) 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 ); } });