Search code examples
javascriptcounter

how can I code counting animation with comma in vanilla javascript?


I made counting animations! But, the Designer asked them to take commas every three digits, so I wrote a code to take commas, but I think it should be uploaded in real-time, not just at the end. I'm not used to JavaScript yet. ㅜㅜ How should I fix it?

function counterAnimationHandler() {
  const counters = document.querySelectorAll('.counter ')
  counters.forEach(counter => {
    counter.innerText = '0' //set default counter value

    const updateCounter = () => {
      const target = +counter.getAttribute('data-target') //define increase couter to it's data-target
      const count = +counter.innerText //define increase couter on innerText

      const increment = target / 200 // define increment as counter increase value / speed

      if (count < target) {
        counter.innerText = `${Math.ceil(count + increment)}`;
        setTimeout(updateCounter, 1);
      } else {
        counter.innerText = numberWithCommas(target); //if default value is bigger that date-target, show data-target
      }
    }

    updateCounter() //call the function event
  })

  function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  }
}

counterAnimationHandler();
<div class="counter" data-target="1000000"></div>


Solution

  • I would suggest you keepp a different variable for count with the raw (unformatted) number and then make sure you wrap every update to the UI with numberWithCommas.

    function counterAnimationHandler() {
      const counters = document.querySelectorAll('.counter ')
      counters.forEach(counter => {
        counter.innerText = '0' //set default counter value
        counter.dataset.count = 0;
        const updateCounter = () => {
          const target = +counter.getAttribute('data-target') //define increase couter to it's data-target
          const count = +counter.dataset.count //define increase couter on innerText
    
          const increment = target / 200 // define increment as counter increase value / speed
    
          if (count < target) {
            const newCount = Math.ceil(count + increment);
            counter.dataset.count = newCount;
            counter.innerText = numberWithCommas(newCount);
            setTimeout(updateCounter, 1);
          } else {
            counter.innerText = numberWithCommas(target); //if default value is bigger that date-target, show data-target
          }
        }
    
        updateCounter() //call the function event
      })
    
      function numberWithCommas(x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
      }
    }
    
    counterAnimationHandler();
    <div class="counter" data-target="1000000"></div>