简体   繁体   中英

Jquery animate width percentage for bootstrap progress not working

Actually I am having 2 forms in the project, if the user completes one form and click submit, he will be taken to the next form, so I shown the form progress using the progress bar at the top.

if user completes the first form progress will animate width to 50% and if user completes the second form progress will animate width to 100%.

The problem is that animate of width for 50% is working fine, but animate of width for 100% is throwing some higher range values like 315.***% which makes progress bar not animating properly.

Below is the link for the fiddle, where button1(50%) is for the first form and button2(100%) is for the second form.

https://jsfiddle.net/mohamedmusthafac/yeaht53q/

And here is the jquery code below:-

$(document).ready(function(){
$("#but1").on("click", function(){
$(".progress-bar").stop().animate({width:'50%'}, 1500);
});
$("#but2").on("click", function(){
$(".progress-bar").stop().animate({width:'100%'},1500).stop();
});
});

You gave a solution already but looks like that the behavior might be the way jQuery animate function is behaving. I thought I will provide an answer just to explain the behavior. I am not sure whether it is a bug or intended behavior. To me it looks more like a bug.

When you call animate function, internally it calls an adjustCSS function. The callstack to call the adjustCSS is quite long (animate() -> dequeue() -> doAnimation() -> Animation() -> jquery.map() -> createTween() -> Animation.Tweeners.*0 > adjustCSS()) just in case if you are interested in the flow.

Inside the adjustCSS, the code execution path takes a different set of route when the progress bar is at 0% and takes a different set of route when the progress bar is at 50%.

If you see the adjustCSS

function adjustCSS( elem, prop, valueParts, tween ) {
var adjusted,
    scale = 1,
    maxIterations = 20,
    currentValue = tween ?
        function() {
            return tween.cur();
        } :
        function() {
            return jQuery.css( elem, prop, "" );
        },
    initial = currentValue(),
    unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),

    // Starting value computation is required for potential unit mismatches
    initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
        rcssNum.exec( jQuery.css( elem, prop ) );

if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {

    // Trust units reported by jQuery.css
    unit = unit || initialInUnit[ 3 ];

    // Make sure we update the tween properties later on
    valueParts = valueParts || [];

    // Iteratively approximate from a nonzero starting point
    initialInUnit = +initial || 1;

    do {

        // If previous iteration zeroed out, double until we get *something*.
        // Use string for doubling so we don't accidentally see scale as unchanged below
        scale = scale || ".5";

        // Adjust and apply
        initialInUnit = initialInUnit / scale;
        jQuery.style( elem, prop, initialInUnit + unit );

    // Update scale, tolerating zero or NaN from tween.cur()
    // Break the loop if scale is unchanged or perfect, or if we've just had enough.
    } while (
        scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
    );
}

if ( valueParts ) {
    initialInUnit = +initialInUnit || +initial || 0;

    // Apply relative offset (+=/-=) if specified
    adjusted = valueParts[ 1 ] ?
        initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
        +valueParts[ 2 ];
    if ( tween ) {
        tween.unit = unit;
        tween.start = initialInUnit;
        tween.end = adjusted;
    }
}
return adjusted;
}

When you click the first button, the initialInUnit is 0 and it doesn't go through the if condition

if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {

It jumps straight to the

if ( valueParts ) {

But second time when you click the button, it goes through the first if condition above as the progress bar is already at its 50% width. Now what makes the percentage 315% or whatever number it comes up is where the weirdly behavior is.

When it goes through the if condition, there is a statement:

        jQuery.style( elem, prop, initialInUnit + unit );

Here jQuery styles the element's width property to value in initialInUnit which is the width of the progress bar which is in pixel and it appends the unit in %. So instead of animating the width from 50% to 100%, it animates the width from 315% to 100%. That 315% can change depending on the width of the progress bar.

In fact, you don't even need the second button to replicate the behavior, if you click on the Button 1 second time, you can see it is animating from 315% (or whatever) to 50%.

So I am not sure if it is a bug (though it looks like one). The adjustedCSS might work for other conditions may be. It may be worthwhile to open an issue with jQuery team to check the intended behavior of the initialInUnit value assignment in the adjustCSS function.

The adjustCSS function is part of jQuery code as seen here

i got the solution by using the following code, but still i dont know , why i didnt get the solution using the above approach

$("#but2").on("click", function(){
   $('.progress-bar').animate({'width':($('.progress-bar').parent().width())+'px'}, 3000);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM