Ben
Ben

Reputation: 65

How to make jquery counter work with data from innerHTML

I am trying to make a counter using jquery. This counter works when data is passed into the div directly, but does not work when this data is dynamically appended to the div using .innerHTML call.

Below I have the counter code applied to all elements of .count class and I want this counter to work on the div with id = "users" using the document.getElementById('users').innerHTML = 300; This does not work.

But the following works: <div id="users" class="count">300</div>

$('.count').each(function () {
        $(this).prop('Counter',0).animate({
            Counter: $(this).text()
        }, {
            duration: 5000,
            easing: 'swing',
            step: function (now) {
                $(this).text(Math.ceil(now));
            }
        });
     });
<div id="users" class="count"></div>

document.getElementById('users').innerHTML = 300; 

The output I get while using document.getElementById('users').innerHTML = 300; is 0, but this is unexpected. I have several elements with class count that depend on this counter.

Any help with this would be appreciated.

Upvotes: 2

Views: 494

Answers (3)

Cat
Cat

Reputation: 4226

I'm not totally sure what is meant by "I want this counter to work...", but does this handle your use case?:

const users = document.getElementById("users");
users.innerHTML = "300";
//users.addEventListener("change", console.log(users.innerHTML));

$('.count').each(function () {
  let num = users.innerHTML; // Sets the value dynamically
  $(this).prop('Counter', num).animate({
    Counter: $(this).text()
  }, {
    duration: 5000,
    easing: 'swing',
    step: function (now) {
      $(this).text(Math.ceil(now));
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id="users" class="count">0</p>

Upvotes: 1

Tuhin Das
Tuhin Das

Reputation: 499

@Ben you need to set the innerHTML before you call the counter animation 
document.getElementById('users').innerHTML = 300;

$('.count').each(function () {
        $(this).prop('Counter',0).animate({
            Counter: $(this).text()
        }, {
            duration: 5000,
            easing: 'swing',
            step: function (now) {
                $(this).text(Math.ceil(now));
            }
        });
     });

Upvotes: 2

shrys
shrys

Reputation: 5940

You might want to write document.getElementById('users').innerHTML = 300; before the .each code, because .innerHTML works for me

document.getElementById('users').innerHTML = 300;
$('.count').each(function() {
  $(this).prop('Counter', 0).animate({
    Counter: $(this).text()
  }, {
    duration: 5000,
    easing: 'swing',
    step: function(now) {
      $(this).text(Math.ceil(now));
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="users" class="count"></div>

Or you could add DOMSubtreeModified event, so when the sub-tree is changed your function will be triggered (one is to trigger the event once as we don't want sub-tree event to fire again):

$('.count').one("DOMSubtreeModified", function() {
  $('.count').each(function() {
    $(this).prop('Counter', 0).animate({
      Counter: $(this).text()
    }, {
      duration: 5000,
      easing: 'swing',
      step: function(now) {
        $(this).text(Math.ceil(now));
      }
    });
  });
});
document.getElementById('users').innerHTML = 300;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="users" class="count"></div>

Upvotes: 1

Related Questions