Reputation: 106
I want to implement a counter that counts in the given time duration. If I want to count 100 in one second, then the gap between each count should be 10ms as a result by the time it gets counted 100 it becomes 1 second. For 1000 the gap between each count should be 1ms.
I've tried using setInterval and changing the delay of the counter dynamically based on the number I want to count, but there's a problem with setInterval, it is not working as expected. Other than using setInterval how can I implement this counter in JavaScript. Thank you in advance.
const btn = document.querySelector('button');
const counter1 = document.querySelector('.counter1');
const counter2 = document.querySelector('.counter2');
btn.addEventListener('click', ()=> {
increment(100, counter1);
increment(1000, counter2);
})
const increment = (n, counter) => {
let m = 0;
let time = 1000 / n;
setInterval(() => {
if (m < n) {
m += 1;
counter.textContent = m;
} else clearInterval(this);
}, time);
};
.counter-container {
display: flex;
}
.counter {
margin: 10px;
text-align: center;
}
button {
margin-left: 80px;
};
<div class="counter-container">
<div class="counter">
<h3>Counter1</h3>
<p class="counter1">100</p>
</div>
<div class="counter">
<h3>Counter2</h3>
<p class="counter2">1000</p>
</div>
</div>
<button>start</button>
Upvotes: 0
Views: 630
Reputation: 309
setInterval()
and setTimeout()
are not actually reliable when it comes to timing. I would use a combination of those with javascript's Date.now()
, which returns the number of milliseconds since the browser's/os's epoch. So you could do something like this:w
const btn = document.querySelector('button');
const counter1 = document.querySelector('.counter1');
const counter2 = document.querySelector('.counter2');
btn.addEventListener('click', ()=> {
increment(100, counter1);
increment(1000, counter2);
})
const increment = (n, counter, length=1000) => {
let start = Date.now()
let end = start + length
let interval = length / n;
setInterval(() => {
time = Date.now()
if (time < end) {
count = (time - start) / interval
counter.textContent = count;
} else {
counter.textContent = n;
clearInterval(this)
};
}, interval/2);
};
.counter-container {
display: flex;
}
.counter {
margin: 10px;
text-align: center;
}
button {
margin-left: 80px;
};
<div class="counter-container">
<div class="counter">
<h3>Counter1</h3>
<p class="counter1">100</p>
</div>
<div class="counter">
<h3>Counter2</h3>
<p class="counter2">1000</p>
</div>
</div>
<button>start</button>
Upvotes: 3