Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does changing CSS width behave weird when using short intervals?

The idea is to have a progress bar which loads in 20 seconds from 0% to 100% and then starts over from 0. To accomplish that I use setInterval in combination with jQuery.css('width', '+=0.1%).

One interval counts to 20 seconds, the other one adds 0.1% to the width of a div every 20 milliseconds. Should reach 100% when the first timer is up, right?

But it doesn't. First the width isn't added as intended: it's not beeing counted in 0.1% steps but way more places behind the comma. Second the 20 seconds are over long before reaching 100%. Different browsers give different results here. Chrome comes pretty close to 100% before starting over, Firefox 20 seconds were over when reaching 70% in my site...

Even when using 1% steps instead of 0.1% steps it still doesn't properly add up, I still get places behind the comma although there shouldn't be any.

Example code:

var interval;
$('.progressbar').css('width', '0%');
interval= setInterval(function() {
  $('.progressbar').css('width', '+=0.1%');
}, 20);

setInterval(startLoading, 20000);

function startLoading() {
  clearInterval(interval);
  $('.progressbar').css('width', '0%');
  interval= setInterval(function() {
    $('.progressbar').css('width', '+=0.1%');
  }, 20);
}
.progressbar{
    height: 10px;
    background: #0060ff;
    border-radius:20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div class="progressbar"></div>
like image 388
Danmoreng Avatar asked Jan 02 '23 19:01

Danmoreng


1 Answers

Use css animation or jquery .animate().

You just have to set the duration to 20000 and everything will work fine. If you have to stop it at some point just add a condition around the progressBarLoop function in the animate callback. (I set the duration to 5000 so we don't have to wait 20 second to have the restart)

var stop = false;

function progressBarLoop() {
  $('.progressbar').css('width', '0%');
  $('.progressbar').animate({
    width:'100%'
  }, 5000, 'linear', function() {
    if(!stop) {
      progressBarLoop();
    }
  });
  
}

 progressBarLoop();
.progressbar{
    height: 10px;
    background: #0060ff;
    border-radius:20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div class="progressbar"></div>
like image 164
Alexis Vandepitte Avatar answered Jan 14 '23 13:01

Alexis Vandepitte