I have a number counter and I'm using waypoints to run the counter when the #ticker
div is in view.
The counter starts when the div is in view, so that's not the issue. But here is a use case of my current issue:
16,000+
.15,604+
when it should always end at 16,000+
.Unsure why this is happening?
demo:
$(document).ready(function() {
$('#ticker').waypoint({
handler: function() {
$('.count').each(function() {
const initial = $(this).text()
const format = formatter(initial)
$(this).prop('Counter', 0).animate({
Counter: format.value
}, {
duration: 1500,
easing: 'swing',
step: function(now) {
$(this).text(format.revert(Math.ceil(now)));
}
});
});
},
offset: '100%'
});
})
// keep string after count
function formatter(str) {
const char = 'x'
const template = str.replace(/\d/g, char)
const value = str.replace(/\D/g, '')
function revert(val) {
const valStr = val.toString()
let result = ''
let index = 0
for (let i = 0; i < template.length; i++) {
const holder = template[i]
if (holder === char) {
result += valStr.slice(index, index + 1)
index++
} else {
result += holder
}
}
return result
}
return {
template: template,
value: value,
revert: revert
}
}
.gap{
background: lightgrey;
height: 600px;
}
.gap2{
background: blue;
height: 600px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.min.js"></script>
<div class="gap"></div>
<div id="ticker">
<span class="count counter">16,000+</span>
</div>
<div class="gap2"></div>
If you scroll down till ticker
and wait for 16000 to complete and again scroll up and wait for 16000 to complete and then again come down it will work.
The code is absolutely correct, except this line const initial = $(this).text()
.
You are using a span element text itself to get the maximum counter number.
Whenever you scroll too fast then code will set whatever value present in the span element to the maximum counter. That's why you are getting wired behavior.
Please rewrite your handler code like this
$(document).ready(function () {
var initialValue = $('#ticker .count').text()
$('#ticker').waypoint({
handler: function () {
$('.count').each(function () {
const format = formatter(initialValue)
$(this).prop('Counter', 0).animate({
Counter: format.value
}, {
duration: 1500,
easing: 'swing',
step: function (now) {
$(this).text(format.revert(Math.ceil(now)));
}
});
});
},
offset: '100%'
});
})