]> source.dussan.org Git - jquery.git/commitdiff
Fix #8109, percent animations; fix #11854, wrong this, close gh-808
authorJeffery To <jeffery.to@gmail.com>
Mon, 11 Jun 2012 18:17:36 +0000 (14:17 -0400)
committerDave Methvin <dave.methvin@gmail.com>
Mon, 11 Jun 2012 18:17:36 +0000 (14:17 -0400)
src/effects.js
test/unit/effects.js

index ff1c98d80c7caa1d61b9b603d24e854b6dc43752..7aae8a414508a396a04b6af28fef42e223e74428 100644 (file)
@@ -7,20 +7,38 @@ var fxNow, timerId,
        animationPrefilters = [ defaultPrefilter ],
        tweeners = {
                "*": [function( prop, value ) {
-                       var end, unit,
+                       var end, unit, prevScale,
                                tween = this.createTween( prop, value ),
                                parts = rfxnum.exec( value ),
-                               start = tween.cur();
+                               start = tween.cur(),
+                               scale = 1,
+                               target = start;
 
                        if ( parts ) {
                                end = +parts[2];
                                unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" );
 
                                // We need to compute starting value
-                               if ( unit !== "px" ) {
-                                       jQuery.style( this, prop, (end || 1) + unit);
-                                       start = start * (end || 1) / tween.cur() || 0;
-                                       jQuery.style( this, prop, start + unit);
+                               if ( unit !== "px" && start ) {
+                                       // Iteratively approximate from a nonzero starting point
+                                       // Prefer the current property, because this process will be trivial if it uses the same units
+                                       // Fallback to end or a simple constant
+                                       start = parseFloat( jQuery.style( tween.elem, prop ) ) || end || 1;
+
+                                       do {
+                                               // If previous iteration zeroed out, double until we get *something*
+                                               // Use a string for doubling factor so we don't accidentally see scale as unchanged below
+                                               prevScale = scale = scale || ".5";
+
+                                               // Adjust and apply
+                                               start = start / scale;
+                                               jQuery.style( tween.elem, prop, start + unit );
+
+                                               // Update scale, tolerating zeroes from tween.cur()
+                                               scale = tween.cur() / target;
+
+                                       // Stop looping if scale is unchanged or we've hit the mark
+                                       } while ( scale !== 1 && scale !== prevScale );
                                }
 
                                tween.unit = unit;
index 9e244490d7e804f96349d052470352d4f05e6b0d..48793e234e30f35b2e53eb4d03ea0caed0e7aede 100644 (file)
@@ -1628,4 +1628,22 @@ asyncTest( "multiple unqueued and promise", 4, function() {
        });
 });
 
+asyncTest( "animate does not change start value for non-px animation (#7109)", 1, function() {
+       var parent = jQuery( "<div><div></div></div>" ).css({ width: 284, height: 1 }).appendTo( "#qunit-fixture" ),
+               child = parent.children().css({ fontSize: "98.6in", width: "0.01em", height: 1 }),
+               actual = parseFloat( child.css( "width" ) ),
+               computed = [];
+
+       child.animate({ width: "0%" }, {
+               duration: 1,
+               step: function() {
+                       computed.push( parseFloat( child.css( "width" ) ) );
+               }
+       }).queue( function( next ) {
+               equal( computed[0], actual, "Starting width was unchanged" );
+               next();
+               start();
+       });
+});
+
 } // if ( jQuery.fx )