I am trying to make make my counter work when scrolling.
I have tried Google, StackOverflow and other different sites and the web is full with examples but I cannot figure it out. Can anyone give a tip please?
I have also tried to wrap the code inside $(window).scroll() but it also doesn't seem to work.
const counters = document.querySelectorAll(".count");
const speed = 200;
counters.forEach((counter) => {
const updateCount = () => {
const target = parseInt( counter.getAttribute("data-target"));
const count = parseInt( counter.innerText);
const increment = Math.trunc(target / speed);
console.log(increment);
if (count < target) {
counter.innerText = count increment;
setTimeout(updateCount, 1);
} else {
count.innerText = target;
}
};
updateCount();
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: "verdana", sans-serif;
background: #ffffff;
}
.container {
width: 80%;
margin: auto;
}
.heading {
text-align: center;
font-size: 3.5rem;
font-weight: bold;
padding: 5rem 0;
color: #505050;
}
.counter-container {
display: flex;
justify-content: space-around;
align-items: center;
}
.counter {
text-align: center;
}
.counter h3 {
padding: 0.5rem 0;
font-size: 2.5rem;
font-weight: 800;
}
.counter h6 {
font-size: 2rem;
padding-bottom: 1rem;
}
.icon {
height: 5rem;
width: auto;
}
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;900&display=swap" rel="stylesheet">
<div >
<div >
Resultater
</div>
<div >
<div >
<img src="#" alt="timer" srcset="" >
<h3 data-target="200" >0</h3>
<h6>Text 1</h6>
</div>
<div >
<img src="#" srcset="" >
<h3 data-target="217" >0</h3>
<h6>Text 2</h6>
</div>
<div >
<img src="#" alt="night" srcset="" >
<h3 data-target="511" >0</h3>
<h6>Text 3</h6>
</div>
</div>
</div>
CodePudding user response:
If all you need is to start your timers after the first scroll event, you can add a single scroll
event listener, and make use of the once
config option (So that you only start the animation the first time the user scrolls)
The important part (Where startCounters
is a function which creates your counters):
window.addEventListener('scroll', startCounters, {
once: true
});
Full example:
const counters = document.querySelectorAll(".count");
const speed = 200;
// The code to start the animation is now wrapped in a function
const startCounters = () => {
counters.forEach((counter) => {
const updateCount = () => {
const target = parseInt( counter.getAttribute("data-target"));
const count = parseInt( counter.innerText);
const increment = Math.trunc(target / speed);
if (count < target) {
counter.innerText = count increment;
setTimeout(updateCount, 1);
} else {
count.innerText = target;
}
};
updateCount();
});
}
// On the first scroll in this window, call the function to start the counters
window.addEventListener('scroll', startCounters, {
once: true
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: "verdana", sans-serif;
background: #ffffff;
}
.container {
width: 80%;
margin: auto;
}
.heading {
text-align: center;
font-size: 3.5rem;
font-weight: bold;
padding: 5rem 0;
color: #505050;
}
.counter-container {
display: flex;
justify-content: space-around;
align-items: center;
}
.counter {
text-align: center;
}
.counter h3 {
padding: 0.5rem 0;
font-size: 2.5rem;
font-weight: 800;
}
.counter h6 {
font-size: 2rem;
padding-bottom: 1rem;
}
.icon {
height: 5rem;
width: auto;
}
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;900&display=swap" rel="stylesheet">
<div >
<div >
Resultater
</div>
<div >
<div >
<img src="#" alt="timer" srcset="" >
<h3 data-target="200" >0</h3>
<h6>Text 1</h6>
</div>
<div >
<img src="#" srcset="" >
<h3 data-target="217" >0</h3>
<h6>Text 2</h6>
</div>
<div >
<img src="#" alt="night" srcset="" >
<h3 data-target="511" >0</h3>
<h6>Text 3</h6>
</div>
</div>
</div>