2

I wrote simple JQuery function to count from 0 to specified number in a range of divs with certain class name:

    <div class="number">50%</div>
    <div class="number">75%</div>

this is JQuery code:

$(document).ready(function () {
$(".number").each( function() {
    var percent = $(this).text().replace("%","");
    console.log("test " + percent);

    function countToPercent(percent) {
        var interval = setInterval(counter,25);
        var n = 0;
        function counter() {
            if (n >= percent) {
                clearInterval(interval);
            }
            else {
                n += 1;
                // console.log(n);
                $(this).text(n + "%");
            }
        }
    }

    countToPercent(percent);
})
});

unfortunetly it isn't working now - there is probably a problem within this is line:

$(this).text(n + "%")

i debbuged it using console and commented console.log(n) works - it counts from 0 to specified number. so it has to be problem with selecting correct DOM element.

is it forbidden to use setInterval() with .each() method or with "this" keyword? or is there some bug in the code?

cclf13
  • 71
  • 5

2 Answers2

0

You need to save a context to use it in setInterval

$(document).ready(function () {
$(".number").each( function() {
    var percent = $(this).text().replace("%","");
    console.log("test " + percent);
    var self = this; // fixing context;

    function countToPercent(percent) {
        var n = 0;
        var interval = setInterval(() => {
            if (n >= percent) {
                clearInterval(interval);
            }
            else {
                n += 1;
                // console.log(n);
                $(self).text(n + "%");
            }
        },25);
    }

    countToPercent(percent);
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="number">50%</div>
<div class="number">75%</div>
qiAlex
  • 4,290
  • 2
  • 19
  • 35
0

Your problem is that this keyword does not exist in context of interval scope.

Wrap interval stuff to another scope by providing injecting variables and call it:

    $(function () {
    
      $(".number").each( function() {
        var $this = $(this);
        var percentage = parseFloat($this.text().replace("%",""));
        console.log("test " + percentage);
    
    
        (function(percentage, jqObject) {
          var n = 0;
          var interval = setInterval(function() {
            if(n >= percentage) return clearInterval(interval);
            n++;
            jqObject.text(n + '%');
          }, 25);
        })(percentage, $this);
        
      });
    
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="number">50%</div>
<div class="number">75%</div>

or You may have external function that does same thing:

$(function () {
    
   function animatePercentageProgress(percentage, jqObject) {
      var n = 0;
      var interval = setInterval(function() {
        if(n >= percentage) return clearInterval(interval);
        n++;
        jqObject.text(n + '%');
      }, 25);
   }
    
    $(".number").each( function() {
      var $this = $(this);
      var percentage = parseFloat($this.text().replace("%",""));
      console.log("test " + percentage);  
      animatePercentageProgress(percentage, $this);
    });
        
});
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <div class="number">50%</div>
    <div class="number">75%</div>

or more "functional way":

$(function () {
        
   function animatePercentageProgress(idx, jqObjectPointer) {
      var jqObject = $(jqObjectPointer);
      var percentage = parseFloat(jqObject.text().replace("%",""));

      var n = 0;
      var interval = setInterval(function() {
        if(n >= percentage) return clearInterval(interval);
        n++;
        jqObject.text(n + '%');
      }, 25);
   }

    $(".number").each(animatePercentageProgress);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <div class="number">50%</div>
    <div class="number">75%</div>
num8er
  • 18,604
  • 3
  • 43
  • 57