John Smith
John Smith

Reputation: 8811

How to instantly update a smoothly updating progress bar?

Bit of a specific question but I have a progress bar traveling from 100% to 0% over 10 seconds and I would like to, upon clicking a button, to jump it to whatever percent and continue from there. Here is a fiddle so far:

https://jsfiddle.net/41o6xvyt/

This kinda works except for the fact I have to use a timeout and some instant css switching trickery to get it to work (and even then it may not work on slower computers and it loses however many milliseconds). I was wondering if there was a better way that didn't require timeouts or this kind of hack in order to work.

Upvotes: 3

Views: 1312

Answers (3)

Spencer Wieczorek
Spencer Wieczorek

Reputation: 21565

The reason why you need the setTimeout() it is because the changes are cached by the browser and only applied after the entire script executes. The setTimeout allows one script to execute, then another after the timeout. This allows the CSS changes to be applied. In your example if we only call b() here is what's going on:

$("#first").css({ 'transition-duration' : '0s' });  // Cache change1
$("#first").css("width","50%");                     // Cache change2
$("#first").css({ 'transition-duration' : '5s' });  // Overwrite change1
$("#first").css("width", "0%");                     // Overwrite change2
// Apply style changes

The first changes to transition-duration and width practically never even existed, and never where applied since it was all done at the end of the script.

If you read the offsetHeight property of the element it will flush the cache and apply the changes, this will force the changes made to the CSS to be applied.

Also you will need to do is change the progress bars width to be set in CSS rather than as an attribute (as the flush only affects the CSS and not the items directly in style).

$("#report_jump").click(function(){
    $("#first").css({ 'transition-duration' : '0s' });
    $("#first").css("width","50%");
    $("#first")[0].offsetHeight; // flush CSS, the above changes will now be applied
    b();
});

Fiddle Example


Note

The "instant css switching trickery" isn't really trickery. We simply want to change the width to 50% and do so in 0 seconds. That's why the 'transition-duration' : '0s' is necessary.

Upvotes: 2

Rohit Kumar
Rohit Kumar

Reputation: 1958

I edited your codes and found a solution

$("#report_start").click(function(){
     $("#first").removeClass('notransition');
     $("#first").css("width","0%");
});

$("#report_jump").click(function(){
    $("#first").css("width","50%");
    $("#first").addClass('notransition'); // to remove transition
    var dummyDelay=$("#first").width();   
   $("#report_start").trigger('click');
 });

And add class in css

.notransition { 
  -webkit-transition: none !important; 
  -moz-transition: none !important; 
  -o-transition: none !important; 
  -ms-transition: none !important; 
  transition: none !important; 
} 

See live https://jsfiddle.net/mailmerohit5/jbL3n4kj/

Upvotes: 0

kavinhuh
kavinhuh

Reputation: 739

you could try using keyframe http://jsfiddle.net/j44gbwna/3/

@keyframes loader {
    0% {left: 0px;}
    99% { left: 100%;} 
}

@-webkit-keyframes loader {
    0% {width: 0%;left:0;right:0}
    50% { width: 100%;left:0;right:0} 
    99% { width: 0%;left:100%;right:0} 
}

Upvotes: 1

Related Questions