Home > Enterprise >  setInterval stop at one percent
setInterval stop at one percent

Time:09-04

I'm trying to animate three counters simultaneously by setInterval.

The counters should stop at 10, 20, and 30 respectively, I have saved these numbers in an array data, and passed them into the parameter of setInterval, and then they should have stopped when the variable counter1, counter2, counter3 is more than or equal to their number 10, 20, 30 by clearInterval(this).

The problem is that they all stop at 1%, I don't know why...

const data = ['10', '20', '30'],
  item = document.getElementsByClassName('test');
  
let counter1 = 0,
  counter2 = 0,
  counter3 = 0;

function go(current, data, item) {
  if (current >= data) {
    clearInterval(this);
  } else {
    current  ;
    item.textContent = current   '%';
  }
}

let go1 = setInterval(go, 10, counter1, data[0], item[0]),
  go2 = setInterval(go, 10, counter2, data[1], item[1]),
  go3 = setInterval(go, 10, counter3, data[2], item[2]);
<p >0</p>
<p >0</p>
<p >0</p>

CodePudding user response:

It can be simplified a lot by simply passing an index that will refer to items data and counters arrays.

const data = [10, 20, 30],
  items = Array.from(document.getElementsByClassName('test'));

let counters = [0, 0, 0]

function go(index) {
  if (counters[index] >= data[index]) {
    clearInterval(this);
  } else {
    items[index].textContent =   counters[index]   '%';
  }
}

let intervals = items.map((item, index) => setInterval(go, 100, index))
<p >0</p>
<p >0</p>
<p >0</p>

CodePudding user response:

Your counter variables outside the callback will not be affected by counter inside the callback. Instead, use an array of counters and pass in the index of the counter to examine.

const data = ['10', '20', '30'],
  item = document.getElementsByClassName('test');
  
let counters = [0, 0, 0];

function go(index, data, item) {
  if (counters[index] >= data) {
    clearInterval(this);
  } else {
    counters[index]  ;
    item.textContent = counters[index]   '%';
  }
}

let go1 = setInterval(go, 10, 0, data[0], item[0]),
  go2 = setInterval(go, 10, 1, data[1], item[1]),
  go3 = setInterval(go, 10, 2, data[2], item[2]);
<p >0</p>
<p >0</p>
<p >0</p>

It would also be possible to simplify so that you pass only the index, and then use it for the data and item arrays.

CodePudding user response:

The value of current never changes because your interval callback will always be called with the same values. I would use setTimeout instead only calling go with updated arguments if current <= data.

const data = ['10', '20', '30'];
const item = document.getElementsByClassName('test');
  
let counter1 = 0;
let counter2 = 0;
let counter3 = 0;

function go(current, data, item) {
  if (current <= data) {
    item.textContent = current   '%';
    setTimeout(go, 10,   current, data, item);
  }
}

go(counter1, data[0], item[0]);
go(counter2, data[1], item[1]);
go(counter3, data[2], item[2]);
<p >0</p>
<p >0</p>
<p >0</p>

  • Related