Counter-Up icon indicating copy to clipboard operation
Counter-Up copied to clipboard

How can the count start again if I scroll back up to the number?

Open klausabio opened this issue 6 years ago • 9 comments

Lets say I have a counting number. I scroll to it, it works great, then I do some more scrolling down the page, then I go up again back to it. I would like to see the count again from zero, is that possible?

klausabio avatar Dec 08 '17 14:12 klausabio

@klausabio it because waypoints remove option once. Temporary fix: Use this.desktop, and set handler for waypoints

/*!
* jquery.counterup.js 1.0
*
* Copyright 2013, Benjamin Intal http://gambit.ph @bfintal
* Released under the GPL v2 License
*
* Date: Nov 26, 2013
*/
(function( $ ){
  "use strict";

  $.fn.counterUp = function( options ) {

    // Defaults
    var settings = $.extend({
        'time': 400,
        'delay': 10
    }, options);

    return this.each(function(){

        // Store the object
        var $this = $(this);
        var $settings = settings;

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = $this.text();
            var isComma = /[0-9]+,[0-9]+/.test(num);
            num = num.replace(/,/g, '');
            var isInt = /^[0-9]+$/.test(num);
            var isFloat = /^[0-9]+\.[0-9]+$/.test(num);
            var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0;

            // Generate list of incremental numbers to display
            for (var i = divisions; i >= 1; i--) {

                // Preserve as int if input was int
                var newNum = parseInt(num / divisions * i);

                // Preserve float if input was float
                if (isFloat) {
                    newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces);
                }

                // Preserve commas if input had commas
                if (isComma) {
                    while (/(\d+)(\d{3})/.test(newNum.toString())) {
                        newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1'+','+'$2');
                    }
                }

                nums.unshift(newNum);
            }

            $this.data('counterup-nums', nums);
            $this.text('0');

            // Updates the number until we're done
            var f = function() {
                $this.text($this.data('counterup-nums').shift());
                if ($this.data('counterup-nums').length) {
                    setTimeout($this.data('counterup-func'), $settings.delay);
                } else {
                    delete $this.data('counterup-nums');
                    $this.data('counterup-nums', null);
                    $this.data('counterup-func', null);
                }
            };
            $this.data('counterup-func', f);

            // Start the count up
            setTimeout($this.data('counterup-func'), $settings.delay);
            // Destroy waypoint
            this.destroy();
        };

        // Perform counts when the element gets into view
        $this.waypoint({ offset: '100%', handler: counterUpper});
    });

  };

})( jQuery );

tranlehaiquan avatar Dec 13 '17 18:12 tranlehaiquan

A very simple fix is to use a variable rather than getting the data directly from the DOM Node. The code stores the DOM Reference but not the starting number. So the fix would be...

Search in the code for this part:

        // Store the object
        var $this = $(this);
        var $settings = settings;

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = $this.text();

and add a var origValue = $this.text(); before the counterUpper function, to save the original dom node value. Also, the code uses num = $this.text() to get the dom node value, and you should replace it with num = origValue;, so that it will be like this:

        // Store the object
        var $this = $(this);
        var $settings = settings;
        var origValue = $this.text();

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = origValue;

Done :)

dnunes avatar Mar 01 '18 21:03 dnunes

Thanks @dnunes it's working.

firestar300 avatar Mar 15 '18 15:03 firestar300

hi @dnunes. im from brazil too. can u help me? i posted this:

"Hi, is possible to have the counter in a loop, in time interval. an e.g: when scroll target to numbers, counter starts, from "0" to " 13.423"; and then, in five seconds (an eg), the counter resumes the count, from 0 to 13.423 again. its possible? like a 'loop' with interval. 2) i want to use 1.300.000, but returns "NAn" for me. how can i use this format of numbers??" Tks a lot!

marcelomgerais avatar May 01 '18 14:05 marcelomgerais

Hey, @marcelomgerais. Sorry for the delay, I missed the notification.

First, re-running the counter is kind of a hard question because it requires us to "stop" the looping once the screen scrolls off, so it can restart when it becomes visible again. AFAIK there is no such funcionality on library (Waypoints) Counter Up uses. You could simply run it in a loop forever every 5-secs after it finishes (it would start when the user scrolls and then will keep looping). This is subideal because if the user scrolls again it could be mid-counting and would not start from 0, but is the best you can right now. This change would require a somehow bigger modification to the code (some 6 or 7 lines, maybe). You would need to store the array with the numbers and run the current "shifting" process in a copy of this array, so you can reset the array later to re-run. You would enqueue the restart using the "else" that detects the end of the counting at line 65.

For the second question, currently Counter Up runs a "parseInt" in the data you input and it cannot really understand any complex masks (it accepts commas as thousands separator). But as the code store the pre-calculated data in an array, you can easily pass the number through a masking function before storing it at line 54 with

nums.unshift(MASKING_FUNCTION(newNum, PARAMS_IF_NEEDED));

dnunes avatar May 20 '18 22:05 dnunes

A very simple fix is to use a variable rather than getting the data directly from the DOM Node. The code stores the DOM Reference but not the starting number. So the fix would be...

Search in the code for this part:

        // Store the object
        var $this = $(this);
        var $settings = settings;

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = $this.text();

and add a var origValue = $this.text(); before the counterUpper function, to save the original dom node value. Also, the code uses num = $this.text() to get the dom node value, and you should replace it with num = origValue;, so that it will be like this:

        // Store the object
        var $this = $(this);
        var $settings = settings;
        var origValue = $this.text();

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = origValue;

Done :)

It is working! Thanks a lot! Save my day!

veselinminchev avatar Sep 11 '18 18:09 veselinminchev

A very simple fix is to use a variable rather than getting the data directly from the DOM Node. The code stores the DOM Reference but not the starting number. So the fix would be...

Search in the code for this part:

        // Store the object
        var $this = $(this);
        var $settings = settings;

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = $this.text();

and add a var origValue = $this.text(); before the counterUpper function, to save the original dom node value. Also, the code uses num = $this.text() to get the dom node value, and you should replace it with num = origValue;, so that it will be like this:

        // Store the object
        var $this = $(this);
        var $settings = settings;
        var origValue = $this.text();

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = origValue;

Done :)

Not worked for me !!

KyawSoeAung116 avatar Oct 10 '19 10:10 KyawSoeAung116

A very simple fix is to use a variable rather than getting the data directly from the DOM Node. The code stores the DOM Reference but not the starting number. So the fix would be... Search in the code for this part:

        // Store the object
        var $this = $(this);
        var $settings = settings;

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = $this.text();

and add a var origValue = $this.text(); before the counterUpper function, to save the original dom node value. Also, the code uses num = $this.text() to get the dom node value, and you should replace it with num = origValue;, so that it will be like this:

        // Store the object
        var $this = $(this);
        var $settings = settings;
        var origValue = $this.text();

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = origValue;

Done :)

It is working! Thanks a lot! Save my da

A very simple fix is to use a variable rather than getting the data directly from the DOM Node. The code stores the DOM Reference but not the starting number. So the fix would be... Search in the code for this part:

        // Store the object
        var $this = $(this);
        var $settings = settings;

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = $this.text();

and add a var origValue = $this.text(); before the counterUpper function, to save the original dom node value. Also, the code uses num = $this.text() to get the dom node value, and you should replace it with num = origValue;, so that it will be like this:

        // Store the object
        var $this = $(this);
        var $settings = settings;
        var origValue = $this.text();

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = origValue;

Done :)

It is working! Thanks a lot! Save my day!

Really? which version of waypoint do you use. I stuck for that animation. help plz.

kyaw-soe-aung avatar Oct 13 '19 01:10 kyaw-soe-aung

A very simple fix is to use a variable rather than getting the data directly from the DOM Node. The code stores the DOM Reference but not the starting number. So the fix would be...

Search in the code for this part:

        // Store the object
        var $this = $(this);
        var $settings = settings;

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = $this.text();

and add a var origValue = $this.text(); before the counterUpper function, to save the original dom node value. Also, the code uses num = $this.text() to get the dom node value, and you should replace it with num = origValue;, so that it will be like this:

        // Store the object
        var $this = $(this);
        var $settings = settings;
        var origValue = $this.text();

        var counterUpper = function() {
            var nums = [];
            var divisions = $settings.time / $settings.delay;
            var num = origValue;

Done :)

Thanks, it worked for me.

esjdev avatar Mar 04 '20 01:03 esjdev