themis93
themis93

Reputation: 119

Loop over a function that uses setInterval (jQuery )

I want show and hide a progress bar 10 times. That's why I use a for loop, in which I call the function oneLoop. oneLoop calls the frame function every 100sec. Frame function is used to change the progress bar.

However, the for loop is executed only once. I don't want to use another setInterval function to execute the oneloop function, because unsynchronous events may happen during the intervals and then things become very bad. How can I achieve to execute the oneLoop 10 times and every execution to start after the previous has ended?

The code:

for(var i=0;i<10;i++){
    $(".progress").show();
  var w = {j:100};
  oneLoop(w);
}

function oneLoop(w){

  timerId = setInterval(function(){
    frame(w)
  },100);
}

function frame(w) {
  //when the percentage becomes zero, the progress bar closes 
  if (w.j === 0) {
    clearInterval(timerId);
    $(".progress").fadeOut(); 
  }
  //the percentage is descreased be 1%
  else {
    w.j = w.j - 1;
    $(".progress-bar").width(w.j + '%'); 
  }
}

And the HTML:

<div class="progress">
  <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
  </div>
</div>

https://jsfiddle.net/DTcHh/27828/

Upvotes: 1

Views: 349

Answers (2)

m87
m87

Reputation: 4523

try this...

var p = 100;
var timerId;
function oneLoop() {
  timerId = setInterval(function() {
    p -= 1;
    frame();
  }, 100);
}
function frame() {
  if (p === 0) {
    $(".progress").fadeOut();
    clearInterval(timerId);
  } else {
    $(".progress-bar").width(p + '%');
  }
}
oneLoop();
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="progress">
  <div class="progress-bar progress-bar-success" style="width: 100%" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
  </div>
</div>

Upvotes: 0

n00dl3
n00dl3

Reputation: 21564

No need for a for loop :

let progress=$(".progress");
let progressBar=$(".progress>.progress-bar");
let count=0;
let maxCount=10;
function run(){
  progressBar.width('100%'); 
  progress.fadeIn(400,()=>{
  	let w={j:100};
    let timerId=setInterval(()=>{
      if (w.j === 0) {
        count++;
        clearInterval(timerId);
        progress.fadeOut(400,()=>{
        if(count<maxCount)
          run();
        else
          console.log("ended")
        });
      }
      else {
        w.j = w.j - 1;
        progressBar.width(w.j + '%'); 
      }
    },100);
  });
}
run();
.progress{
  width:100px;
  height:20px;
  background-color:blue;
}
.progress-bar{
  background-color:red;
  height:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="progress">
  <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100">
  </div>
</div>

Upvotes: 2

Related Questions