Home > Software engineering >  Counter on scroll in javascript
Counter on scroll in javascript

Time:09-10

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>

  • Related