I have a number ticker which counts up. For demo purposes, this is how the counter is meant to work. It counts up and then stops.
Now, I'm trying to get the ticker script to execute when the #ticker
is in view. To do this, I'm using waypoints
. However, I'm having the following issues:
#ticker
is in view. In fact, I have to scroll past it and then when I scroll up, it starts to count.Why is this happening?
Demo:
$(document).ready(function() {
$('#ticker').waypoint(function() {
$('.count').each(function() {
const initial = $(this).text()
const format = formatter(initial)
$(this).prop('Counter', 0).animate({
Counter: format.value
}, {
duration: 3000,
easing: 'swing',
step: function(now) {
$(this).text(format.revert(Math.ceil(now)));
}
});
});
});
})
function formatter(str) {
// const delimeter = '-'
const char = 'x'
const template = str.replace(/\d/g, char)
const value = str.replace(/\D/g, '')
function revert(val) {
// need better solution
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;
}
<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="gap"></div>
Waypoint plugin has an option offset
which determines at which position should the handler be triggered, which is by default 0
. This means that your handler will only be triggered when your element reaches the top edge of browser and it will be triggered everytime your element reaches top edge of the browser.
This is whats happening in your case, you just need to pass offset to the Waypoint and it will be fixed.
$(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: 3000,
easing: 'swing',
step: function(now) {
$(this).text(format.revert(Math.ceil(now)));
}
});
});
},
offset: '100%'
});
})
function formatter(str) {
// const delimeter = '-'
const char = 'x'
const template = str.replace(/\d/g, char)
const value = str.replace(/\D/g, '')
function revert(val) {
// need better solution
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;
}
<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="gap"></div>