Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Restart setInterval inside loop after clearInterval

I’m making an animated progress bar with setInterval that will call the function animate to increase the width of the .bar. I need to stop the setInterval when the counter is 100/the width of the bar is 100% and restart it again for the next bar.

The problem is that the for loop seems immediately called the function three times (because the length of the bar is 3) instead of waiting for the current bar to be finished and then only resetting the counter to 0 and restarting the setInterval for the next bar…

I’ve been struggling with this for about an hour, please help.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const items = document.getElementsByClassName('bar');

for (let i = 0; i < items.length; i++) {
  let intervalId,
  counter = 0;
  function animate() {
    if(counter >= 100) {
      clearInterval(intervalId);
      counter = 0;
    } else {
      counter++;
      items[i].style.width = `${counter}%`;
    }
  }
    
  intervalId = setInterval(animate, 10);
}
#main {
  display: flex;
  gap: 30px;
}

.item {
  background-color: gray;
  width: 100%;
  height: 3px;
}

.bar {
  background-color: orange;
  width: 0;
  height: 100%;
}
<div id="main">
  <div class="item">
    <div class="bar"></div>
  </div>
  <div class="item">
    <div class="bar"></div>
  </div>
  <div class="item">
    <div class="bar"></div>
  </div>
</div>

>Solution :

Put the code for a single progress bar in a function, which takes the item index as an argument. Then when you reach the end of one progress bar, you can stop it and call the function for the next one.

const items = document.getElementsByClassName('bar');

function progressBar(i) {
  if (i < items.length) {
    let intervalId,
      counter = 0;

    function animate() {
      if (counter >= 100) {
        clearInterval(intervalId);
        progressBar(i + 1);
      } else {
        counter++;
        items[i].style.width = `${counter}%`;
      }
    }

    intervalId = setInterval(animate, 10);
  }
}

progressBar(0);
#main {
  display: flex;
  gap: 30px;
}

.item {
  background-color: gray;
  width: 100%;
  height: 3px;
}

.bar {
  background-color: orange;
  width: 0;
  height: 100%;
}
<div id="main">
  <div class="item">
    <div class="bar"></div>
  </div>
  <div class="item">
    <div class="bar"></div>
  </div>
  <div class="item">
    <div class="bar"></div>
  </div>
</div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading