Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I correctly use setInterval and clearInterval to switch between two different functions?

For practice I am trying to display a number that increments from 0 - 9, then decrements from 9 - 0, and infinitely repeats.

The code that I have so far seems to be close, but upon the second iteration the setInterval calls of my 2 respective functions countUp and countDown seem to be conflicting with each other, as the numbers displayed are not counting in the intended order... and then the browser crashes.

Here is my code:

<!DOCTYPE html>
<html>
    <head>
        <title>Algorithm Test</title>
    </head>

    <body onload = "onloadFunctions();">
        <script type = "text/javascript">
            function onloadFunctions()
            {
                countUp();
                setInterval(countUp, 200);
            }

            var count = 0;
            function countUp()
            {
                document.getElementById("here").innerHTML = count;
                count++;

                if(count == 10)
                {
                    clearInterval(this);
                    countDown();
                    setInterval(countDown, 200);
                }
            }
            function countDown()
            {
                document.getElementById("here").innerHTML = count;
                count--;

                if(count == 0)
                {
                    clearInterval(this);
                    countUp();
                    setInterval(countUp, 200);
                }       
            }
        </script>

        From 0 - 9, up and down:&nbsp;&nbsp;<div id = "here"></div>
    </body>
</html>
like image 318
Ian Campbell Avatar asked May 07 '12 16:05

Ian Campbell


People also ask

Can I clearInterval in setInterval?

Calling clearInterval() inside setInterval() has no effect But after calling clearInterval(), it will continue to execute.

How do you use setInterval method?

The setInterval() method calls a function at specified intervals (in milliseconds). The setInterval() method continues calling the function until clearInterval() is called, or the window is closed. 1 second = 1000 milliseconds.

What is the correct syntax to call the setInterval () function?

The setInterval method has the same syntax as setTimeout : let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...)

Does clearInterval stop the function?

I did make a fiddle to test it, and it turns out clearInterval stops all future execution, even those that have already be queued.


4 Answers

You need to capture the return value from setInterval( ... ) into a variable as that is the reference to the timer:

var interval;
var count = 0;

function onloadFunctions()
{
    countUp();
    interval = setInterval(countUp, 200);
}

/* ... code ... */

function countUp()
{
    document.getElementById("here").innerHTML = count;
    count++;

    if(count === 10)
    {
        clearInterval(interval);
        countUp();
        interval = setInterval(countUp, 200);
    }
}
like image 186
Alex Avatar answered Sep 26 '22 17:09

Alex


@Claude, you are right, the other solution I proposed was too different from original code. This is another possible solution, using setInterval and switching functions:

function onloadFunctions() {
    var count = 0;
    var refId = null;
    var target = document.getElementById("aux");

    var countUp = function() {
        target.innerHTML = count;
        count ++;
        if(count >= 9) {
            window.clearInterval(refId);
            refId = window.setInterval(countDown, 500);
        }
    }

    var countDown = function() {
        target.innerHTML = count;
        count --;
        if(count <= 0) {
            window.clearInterval(refId);
            refId = window.setInterval(countUp, 500);
        }
    }
    refId = window.setInterval(countUp, 500);
}
like image 23
Gerardo Lima Avatar answered Sep 25 '22 17:09

Gerardo Lima


clearInterval(this);. You can't do that. You need to save the return value from setInterval.

var interval;
function onloadFunctions()
{
    countUp();
    interval = setInterval(countUp, 200);
}

var count = 0;
function countUp()
{
    document.getElementById("here").innerHTML = count;
    count++;

    if(count == 10)
    {
        clearInterval(interval);
        countDown();
        interval = setInterval(countDown, 200);
    }
}
function countDown()
{
    document.getElementById("here").innerHTML = count;
    count--;

    if(count == 0)
    {
        clearInterval(interval);
        countUp();
        interval = setInterval(countUp, 200);
    }       
}
like image 44
Rocket Hazmat Avatar answered Sep 22 '22 17:09

Rocket Hazmat


try this:

...
<body onload = "onloadFunctions();">

    <script>
        var cup, cdown; // intervals
        var count = 0,
            here  = document.getElementById("here");

        function onloadFunctions() {
            cup = setInterval(countUp, 200);
        }

        function countUp() {
            here.innerHTML = count;
            count++;

            if(count === 10) {
                clearInterval(cup);
                cdown = setInterval(countDown, 200);
            }
        }
        function countDown() {   
            here.innerHTML = count;
            count--;

            if(count === 0) {
                clearInterval(cdown);
                cup = setInterval(countUp, 200);
            }       
        }
    </script>

    From 0 - 9, up and down:&nbsp;&nbsp;<div id = "here"></div>
</body>

you could also create a single reference to #here element. Use always === instead of ==

like image 40
Fabrizio Calderan Avatar answered Sep 22 '22 17:09

Fabrizio Calderan