jQuery animated number counter from zero to value
Your this
doesn't refer to the element in the step callback, instead you want to keep a reference to it at the beginning of your function (wrapped in $this
in my example):
$('.Count').each(function () {
var $this = $(this);
jQuery({ Counter: 0 }).animate({ Counter: $this.text() }, {
duration: 1000,
easing: 'swing',
step: function () {
$this.text(Math.ceil(this.Counter));
}
});
});
Update: If you want to display decimal numbers, then instead of rounding the value with Math.ceil
you can round up to 2 decimals for instance with value.toFixed(2)
:
step: function () {
$this.text(this.Counter.toFixed(2));
}
IMPORTANT: It seems like a small difference but you should really use a data attribute to hold the original number to count up to. Altering the original number can have un-intended consequences. For instance, I'm having this animation run everytime an element enters the screen. But if the element enters, exits, and then enters the screen a second time before the first animation finishes, it will count up to the wrong number.
HTML:
<p class="count" data-value="200" >200</p>
<p class="count" data-value="70" >70</p>
<p class="count" data-value="32" >32</p>
JQuery:
$('.count').each(function () {
$(this).prop('Counter', 0).animate({
Counter: $(this).data('value')
}, {
duration: 1000,
easing: 'swing',
step: function (now) {
$(this).text(this.Counter.toFixed(2));
}
});
});
What the code does, is that the number 8000 is counting up from 0 to 8000. The problem is, that it is placed at the middle of quite long page, and once user scroll down and actually see the number, the animation is already dine. I would like to trigger the counter, once it appears in the viewport.
JS:
$('.count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).text()
}, {
duration: 4000,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now));
}
});
});
And HTML:
<span class="count">8000</span>
this
inside the step callback isn't the element but the object passed to animate()
$('.Count').each(function (_, self) {
jQuery({
Counter: 0
}).animate({
Counter: $(self).text()
}, {
duration: 1000,
easing: 'swing',
step: function () {
$(self).text(Math.ceil(this.Counter));
}
});
});
Another way to do this and keep the references to this
would be
$('.Count').each(function () {
$(this).prop('Counter',0).animate({
Counter: $(this).text()
}, {
duration: 1000,
easing: 'swing',
step: function (now) {
$(this).text(Math.ceil(now));
}
});
});
FIDDLE