Home > OS >  How to create a CountUp between two numbers with Jquery?
How to create a CountUp between two numbers with Jquery?

Time:12-09

How to create a countup between two numbers with Jquery with intervals 15 and slowdown similar to the GIF image below?

enter image description here I can't reproduce this effect.

$('.count').each(function () {
  var $this = $(this);
  jQuery({ Counter: 1243234 }).animate({ Counter: $this.attr('data-stop') }, {
    useGrouping: true,
    separator: ".",
    decimal: ",",
    speed: 99999,
    duration: 9999999,
    refreshInterval: 300,
    easing: 'swing',
    step: function (now) {
      $this.text(Math.ceil(now));
    }
  });
});
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  </head>
  <body>
    <span  data-stop="3256986">3256986</span> Total downloads <br>
  </body>
</html>

CodePudding user response:

Here's a solution using .data to store the current value and setTimeout to loop. Change the timeout (150 here) to adjust the speed. Same concepts can be used for a non-jquery solution.

Storing the current value in the element's data means:

  • stored as an int, so no need to parse the text
  • function can be used for multiple elements without them interfering (if you used global variables, this would be an issue)

$("[data-stop]").each(function() {
    countCounter(this);
})

function countCounter(element) {
   var $this = $(element);
   var counter = $this.data("current") || ($this.text()*1);
   var stop = $this.data("stop");
   //console.log(counter, stop)
   counter  = 15;
   if (counter > stop) counter = stop;
   
   $this.text(counter.toLocaleString())
   $this.data("current", counter)
   
   if (counter < stop)
        setTimeout(() => countCounter(element), 150);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span  data-stop="3256986">3256700</span> Total downloads
<br>

CodePudding user response:

To replicate what you have in the GIF, you could create a simple 1-second interval that changes the value of an element's textContent property. Below is a simple approach. You should update it to make sure the start value and end value are valid, etc.

// Specify a selector, start/end numbers, and increment size
graduallyIncrement(".number", 1234, 1498, 15);

function graduallyIncrement ( selector, start, end, incrementBy ) {

    // Start with an initial value, and an element reference
    let currentValue = start;
    let element = document.querySelector(selector);
  
    // Update our element to show our initial value
    element.textContent = currentValue.toLocaleString();
  
    // Create an interval to run every 1 second
    let interval = setInterval(() => {

        // Determine next number. This may be our current
        // number   15, or it may be the end number.
        let nextNumber = Math.min(end, currentValue  = incrementBy);
    
        // Update our element to show the new number
        element.textContent = nextNumber.toLocaleString();
    
        // Determine whether or not to stop updating
        if ( nextNumber === end ) {
          clearInterval(interval);
        }
  
    }, 1000);

}
<div >1,243,234</div>

Other ways to improve would be to make this a Promise, which resolves when the final number is met. Or pass it a callback function which can be called once the process is complete. Here's how you could use Promises to determine when the counting has completed:

graduallyIncrement(".number", 1234, 1498, 15).then(() => {
    alert("Done counting!");
});

async function graduallyIncrement(selector, current, end, incrementBy) {

    // Start with an initial value, and an element reference
    let element = document.querySelector(selector);

    // Update our element to show our initial value
    element.textContent = current.toLocaleString();

    return new Promise(resolve => {

        // Create an interval to run every 1 second
        let interval = setInterval(() => {

            // Determine next number. This may be our current
            // number   15, or it may be the end number.
            current = Math.min(end, current  = incrementBy);

            // Update our element to show the new number
            element.textContent = current.toLocaleString();

            // Using a setTimeout lets the textContent update
            // complete before we show our ALERT
            setTimeout(() => {
                // Determine whether or not to stop updating
                if (current === end) {
                    clearInterval(interval);
                    resolve();
                }
            }, 0);

        }, 1000);

    });

}
  • Related