Search code examples
jquerynumbersjquery-animatecountdown

Animated numbers (semi-countdown) with JQuery?


I am trying to make a numerical value, say 5000, quickly change to another value, say 4000, using JQuery. Right now I do this fine using:

mod(".class",4000,"add");

function mod(id,value,type){
    var numb = $(id).html();
    var current_value = parseInt(numb);
    do {
        if(type == "add")
            increment(id);
        else
            decrement(id);
        current_value = parseInt(numb);
    }while(current_value != value);

    function decrement(id){
        $(id).html(current_value-1);
    }

    function increment(id){
        $(id).html(current_value+1);
    }
}

I know it's probably not the best way to go about it but what I need for it to do is countdown (or up) the numbers very quickly from the current value to the set value. What I intended with this method was to have a delay using setInterval or setTimeout however that makes the whole script fail pretty badly.

Any advice is appreciated, however I would prefer not to use large plugins for this seemingly simple task.


Solution

  • When I ran the code you supplied, I was caught in an infinite loop. At the end of the do loop, you have

    current_value = parseInt(numb);

    but the value of numb is only set at the beginning of the function, so it goes on forever. If you change that to

    current_value = parseInt($(id).html());

    then it works fine. Except that it appears to happen instantly.

    I hacked up a method to achieve the animation using timeouts that seems to work fairly well, but as I'm still fairly new to javascript I don't know if there is a more efficient approach or not. Just tweak the second param passed to setTimeout to get the desired speed. And if you want to change the increment/decrement value, just change the deceleration of dir.

    function mod2(id, value) {
        var numb = $(id).html();
        var current_value = parseInt(numb);
    
        // determine direction to go
        var dir = 1;
        if (current_value - value > 0) {
            dir *= -1;
        }
        getThere(id, current_value, value, dir);
    }
    
    function getThere(id, current_value, target_value, dir) {
        current_value += dir;
        $(id).html(current_value);
        if (current_value != target_value) {
            setTimeout("getThere('"+id+"',"+current_value+","+target_value+","+dir+")", 10);
        }
    }