Following is the code of a counter. The problem is it runs first time correct but every other time i hit the button the count in decremented. Like for first time 100, second time 45, third time 12 and so on !!!
i have set all values of variable to 0 at the end but still it runs the same way any solution?
<div>
<button onclick="runAnimations()">Clients counter</button>
</h2>
<div class="panel">
<ul>
<li>
<span data-count="250" class="countup">250</span>+
</li>
<li>
<span data-count="500" class="countup">500</span>+
</li>
<li>
<span data-count="100" class="countup">100</span>+
</li>
</ul>
</div>
// How long you want the animation to take, in ms
const animationDuration = 2000;
// Calculate how long each ‘frame’ should last if we want to update the animation 60 times per second
const frameDuration = 1000 / 60;
// Use that to calculate how many frames we need to complete the animation
const totalFrames = Math.round( animationDuration / frameDuration );
// An ease-out function that slows the count as it progresses
const easeOutQuad = t => t * ( 2 - t );
// The animation function, which takes an Element
const animateCountUp = el => {
let frame = 0;
const countTo = parseInt( el.innerHTML, 10 );
// Start the animation running 60 times per second
const counter = setInterval( () => {
frame++;
// Calculate our progress as a value between 0 and 1
// Pass that value to our easing function to get our
// progress on a curve
const progress = easeOutQuad( frame / totalFrames );
// Use the progress value to calculate the current count
const currentCount = Math.round( countTo * progress );
// If the current count has changed, update the element
if ( parseInt( el.innerHTML, 10 ) !== currentCount ) {
el.innerHTML = currentCount;
}
// If we’ve reached our last frame, stop the animation
if ( frame === totalFrames ) {
clearInterval( counter );
}
}, frameDuration );
};
// Run the animation on all elements with a class of ‘countup’
const runAnimations = () => {
const countupEls = document.querySelectorAll( '.countup' );
countupEls.forEach( animateCountUp );
animationDuration = 0;
frameDuration = 0;
totalFrames = 0;
easeOutQuad = 0;
animateCountUp = 0;
countTo = 0;
progress = 0;
runAnimations = 0;
currentCount = 0;
frame = 0;
countupEls = 0;
};
First of all, setting those values to 0
is not a good idea especially because most of them are const
so it shouldn't even be possible. I think the problem with the code is that somehow the runAnimations
function is called too early on the same elements and since you pick the current text of the element as the end number for the counter, if the animation is currently running for that element already it will just pick a lower number for the second run because that is what the innerHTML
is at that moment. To make sure this doesn't happen it would be a better approach to store the number as a data attribute like <div data-count="100" class="countup"></div>
and as that never changes unlike the innerHTML
of the elements, you can make sure your code uses the correct value every run.
Problem is solved by doing as you said above.
<div data-count="100" class="countup"></div>
const countTo = parseInt( el.getAttribute('data-count'), 10 );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.