Search code examples
jquerynumberscounterincrement

Increment a counter by a user specified amount each time


I'm using the following code and am trying to work out how to increment a number by say 10 or 100 (a user-specified amount) until it reaches the countTo value.

The code below is working fine but incrementing by 1 each time.

function countUp() {
    $('.countup.counter span.number').each(function() {
        var num = jQuery(this), 
        countFrom = num.attr("data-from"), 
        countTo = num.attr("data-count"), 
        countIncrement = num.attr("data-increment"), 
        countSpeed = num.attr("data-duration");
        var decimal = 0;
        if (countTo.indexOf(".") > 0) { 
            decimal = countTo.toString().split(".")[1].length; 
        }
        $({ countNum: countFrom}).animate({ countNum: countTo }, {
            duration: parseInt(countSpeed), easing:"swing", 
            step: function() {
                num.text(parseFloat(this.countNum).toFixed(decimal));
            }, complete: function() {
                num.text(this.countNum);
            }
        });
    });
}

So for the example below I'd like it to count 0...100...200...300...400...500...600...700...800...900...1000.45

<div class="counter"><span class="prefix">£</span><span class="number" data-increment="100" data-from="500" data-count="1000.45" data-duration="2000"></span><span class="suffix"></span></div>

Solution

  • Using .animate isn't the same as a for (let i = countFrom; i<countTo; i+=countIncrement) so you can't increment by an amount over time.

    You either increment by an amount (as in the for above) or you animate over time.

    Having said that, you can provide the output in increments, using this answer:

    var val = parseFloat(this.countNum);
    num.text((Math.ceil(val/countIncrement)*countIncrement).toFixed(decimal));
    

    Giving updated snippet:

    $('.counter span.number').each(function() {
      var num = jQuery(this), 
          countFrom = num.attr("data-from"), 
          countTo = num.attr("data-count"), 
          countIncrement = num.attr("data-increment"), 
          countSpeed = num.attr("data-duration");
      var decimal = 0;
      if (countTo.indexOf(".") > 0) { 
        decimal = countTo.toString().split(".")[1].length; 
      }
      $({ countNum: countFrom }).animate({ countNum: countTo }, {
        duration: parseInt(countSpeed), 
        easing:"swing", 
        step: function() {
          var val = parseFloat(this.countNum);
            num.text((Math.ceil(val/countIncrement)*countIncrement).toFixed(decimal));
        }, complete: function() {
          num.text(this.countNum);
        }
      });
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <div class="counter">
      <span class="prefix">£</span>
      <span class="number" data-increment="50" data-from="500" data-count="1000.45" data-duration="2000"></span>
      <span class="suffix"></span>
    </div>