'How to set up the counter when it is detected

In my project, there should be a counter. I have used the "reveal function". I want the counter to start when it goes to "reveal function". And when the bottom-up scrolling is done again, the "reveal function" will be performed again. Given that I used the "reveal function", but when the scroll moves from bottom to top, the counter does not start again. In the code I wrote, the counter runs when the page loads and the "reveal function" has no effect.

How can I solve this problem? Thanks in advance for your guidance.

//counter
const counter = (EL) => {

  const duration = 4000; // Animate all counters equally for a better UX

  const start = parseInt(EL.textContent, 10); // Get start and end values
  const end = parseInt(EL.dataset.counter, 10); // PS: Use always the radix 10!

  if (start === end) return; // If equal values, stop here.

  const range = end - start; // Get the range
  let curr = start; // Set current at start position

  const loop = (raf) => {
    if (raf > duration) raf = duration; // Stop the loop
    const frac = raf / duration; // Get the time fraction
    const step = frac * range; // Calculate the value step
    curr = start + step; // Increment or Decrement current value
    EL.textContent = parseInt(curr, 10); // Apply to UI as integer
    if (raf < duration) requestAnimationFrame(loop); // Loop
  };

  requestAnimationFrame(loop); // Start the loop!
};

document.querySelectorAll("[data-counter]").forEach(counter);
//counter

// reveal
      function reveal() {
        var reveals = document.querySelectorAll(".reveal");

        for (var i = 0; i < reveals.length; i++) {
          var windowHeight = window.innerHeight;
          var elementTop = reveals[i].getBoundingClientRect().top;
          var elementVisible = 10;

          if (elementTop < windowHeight - elementVisible) {
            reveals[i].classList.add("active");
          } else {
            reveals[i].classList.remove("active");
          }
        }
      }

window.addEventListener("scroll", reveal);
// reveal
.container{
   overflow-y: scroll;
}
.pre-reveal{
  width: 100%;
  height: 80vh;
  border: 1px solid red;
}

/* reveal */
.reveal {
  border: 1px solid green;
  position: relative;
  opacity: 0;
  margin-top: 1rem;
}

.reveal.active {
  opacity: 1;
}
/* reveal */
<div class="container">
  <div class="pre-reveal"></div>
  <div class="reveal">
    <span>A: </span>
    <span data-counter="10">0</span>
    <br>
    <span>B: </span>
    <span data-counter="2022">1000</span>
    <br>
    <span>C: </span>
    <span data-counter="0">9999</span>
    <br>
    <span>D: </span>
    <span data-counter="-1000">1000</span>
    <br>
    <span>E: </span>
    <span data-counter="666">0</span>
    <br>
  </div>
</div>


Solution 1:[1]

How to manage the counter with javascript

const counter = (EL) => {
        const duration = 10000;
        const start = parseInt(EL.textContent, 10); 
        const end = parseInt(EL.dataset.counter, 10);
        if (start === end) return;
        const range = end - start; 
        let curr = start;
        let curRaf = null;
          
        const loop = (raf) => {
            if (!curRaf) curRaf = raf; 
            let offsetRaf = raf - curRaf; 
            if (offsetRaf > duration) offsetRaf = duration; 
            const frac = offsetRaf / duration; 
            const step = frac * range;
            curr = start + step; 
            EL.textContent = parseInt(curr, 10); 
            if (offsetRaf < duration) requestAnimationFrame(loop); p
        };
        requestAnimationFrame(loop);
    };

        var hasTriggers = false;
        window.addEventListener('scroll', function() {
            let heightScroll = document.body.scrollTop || document.documentElement.scrollTop;
            let height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
            let scroll = Math.round((heightScroll / height) * 100);
            console.log(scroll);
            if (scroll > 14 && scroll < 17) {
                if (!hasTriggers) document.querySelectorAll("[data-counter]").forEach(counter);
                hasTriggers = true;
            }
        })

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 h.m.p.biologist_programmer