Reputation: 549
This is my script for counting number given the final number (see html). What I want to do is to add a thousands separator. As it is my code will count the number from 0 to eg. 100,000 but it will show : "100000" which doesn't look good.
PS: I've tried toLocaleString() but it didn't work in my code or I didn't use it correctly. The problem with this is that it will not show the thousands separator WHILE animating the counting.
JS
<script>
var a = 0;
$(window).scroll(function() {
var oTop = $('#counter').offset().top - window.innerHeight;
if (a == 0 && $(window).scrollTop() > oTop) {
$('.counter-value').each(function() {
var $this = $(this),
countTo = $this.attr('data-count');
$({
countNum: $this.text()
}).animate({
countNum: countTo
},
{
duration: 5000,
easing: 'swing',
step: function() {
$this.text(Math.floor(this.countNum));
},
complete: function() {
$this.text(this.countNum);
//alert('finished');
}
});
});
a = 1;
}
});
</script>
HTML
<div class="counter-value" data-count="100000">0</div>
Upvotes: 2
Views: 1839
Reputation: 43870
Instead of using divs use elements that'll work for you:
Tag Purpose
<input type='range'>
Store the current offset value: 0 to 100,000
<output></output>
Display the value of <input type='range'>
formatted with Intl.NumberFormat()
<form>
Listens for the input
event and trigger()s a synthetic input
event when user scrolls.
Details commented in Demo
* {
margin: 0;
padding: 0
}
html,
body {
overflow-x: hidden;
font: 600 16px/1.5 Consolas;
width: 100%;
height: 100%;
display: table;
margin: 0 auto;
}
#countDown {
position: relative;
width: 96vw;
height: 12600ch;
overflow-x: hidden;
overflow-y: scroll;
margin-top: 50vh;
z-index:-1;
}
/* The input is hidden because it cannot keep a text of numbers
and commas if it's a type='range'. Don't want to have it as a
type='text' because it's more work to validate */
#counter {
display: none
}
#set {
position: fixed;
width: 15%;
height: 96vh;
z-index: 1;
top: 2vh;
text-align: center;
}
#counterView {
display: block;
margin-top: calc(50vh - 8px);
}
<html>
<head></head>
<body>
<form id='countDown'>
<fieldset id='set'>
<input id='counter' type='range' min='0' max='100000' value='100000'>
<output id="counterView" for='counter'>100,000</output>
</fieldset>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
var a = 0;
$(document).scroll(function() {
/* label#0.mark is a fixed position at the top of viewport
|| The form#countDown is 12596ch high = window.innerHeight
*/
var oTop = $('#set').offset().top + window.innerHeight;
// As the distance between top of viewport decrease...
if ($(window).scrollTop() < (oTop)) {
// The form fires an input event
$('#countDown').trigger('input');
// The input records the distance
$('#counter').val(100315 - Math.round(oTop));
}
});
// The form is bound to input event
$('#countDown').on('input', function(e) {
// Create a special built-in Object
var commas = new Intl.NumberFormat('us-US');
// Get the input's value and convert it into a number
var c = Number($('#counter').val());
// The value of output = value of input
var cV = Number($('#counterView').val());
// Display formatted value in output
$('#counterView').val(commas.format(c));
});
</script>
</body>
</html>
Upvotes: 1
Reputation: 549
Sometimes the answer is right before our eyes..
step: function() {
$this.text(Math.floor(this.countNum).toLocaleString());
},
complete: function() {
$this.text(Number(this.countNum).toLocaleString());;
//alert('finished');
I need to give all the credit to @PatrickEvans. Thank you.
Upvotes: 2