From 6bf3f20d4e0f69ab14702152880a0574623490e2 Mon Sep 17 00:00:00 2001 From: Corey Frang Date: Fri, 18 May 2012 13:48:24 -0400 Subject: [PATCH] Fix #7157. Animation callbacks shouldn't see an element as :animated. Unless of course, there are other animations to be done! Closes gh-775. --- src/effects.js | 56 +++++++++++++++++++++++--------------------- test/unit/effects.js | 11 +++++++++ 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/effects.js b/src/effects.js index 26530a2f8..f7a317ac9 100644 --- a/src/effects.js +++ b/src/effects.js @@ -49,6 +49,7 @@ function callTweeners( animation, props ) { length = collection.length; for ( ; index < length; index++ ) { if ( collection[ index ].call( animation, prop, value ) ) { + // we're done with this property return; } @@ -63,14 +64,33 @@ function Animation( elem, properties, options ) { length = animationPrefilters.length, finished = jQuery.Deferred(), deferred = jQuery.Deferred().always(function( ended ) { - // remove cirular reference - delete animation.tick; + // don't match elem in the :animated selector + delete tick.elem; if ( deferred.state() === "resolved" || ended ) { + // fire callbacks finished.resolveWith( this ); } }), + tick = function() { + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + percent = 1 - ( remaining / animation.duration || 0 ), + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ currentTime ] ); + return false; + } + }, animation = deferred.promise({ elem: elem, props: jQuery.extend( {}, properties ), @@ -87,24 +107,6 @@ function Animation( elem, properties, options ) { animation.tweens.push( tween ); return tween; }, - tick: function() { - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - percent = 1 - ( remaining / animation.duration || 0 ), - index = 0, - length = animation.tweens.length; - - for ( ; index < length ; index++ ) { - animation.tweens[ index ].run( percent ); - } - - if ( percent < 1 && length ) { - return remaining; - } else { - deferred.resolveWith( elem, [ currentTime ] ); - return false; - } - }, stop: function( gotoEnd ) { var index = 0, // if we are going to the end, we want to run all the tweens @@ -132,13 +134,13 @@ function Animation( elem, properties, options ) { callTweeners( animation, props ); - jQuery.extend( animation.tick, { - anim: animation, - queue: animation.opts.queue, - elem: elem - }); - - jQuery.fx.timer( animation.tick ); + jQuery.fx.timer( + jQuery.extend( tick, { + anim: animation, + queue: animation.opts.queue, + elem: elem + }) + ); return animation; } diff --git a/test/unit/effects.js b/test/unit/effects.js index 59a3d3627..b05dfa0cf 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -1509,3 +1509,14 @@ asyncTest( "User supplied callback called after show when fx off (#8892)", 2, fu }); }); }); + +asyncTest("Animation callback should not show animated element as animated (#7157)", 1, function() { + var foo = jQuery( "#foo" ); + + foo.animate({ + opacity: 0 + }, 100, function() { + ok( !foo.is(':animated'), "The element is not animated" ); + start(); + }); +}); \ No newline at end of file -- 2.39.5