Javascript 如何正确使用 setInterval 和 clearInterval 在两个不同的函数之间切换?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10485385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:33:07  来源:igfitidea点击:

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

javascriptanimationcountersetintervalclearinterval

提问by Ian Campbell

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 setIntervalcalls of my 2 respective functions countUpand countDownseem 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:

为了练习,我试图显示一个从 0 - 9 递增,然后从 9 - 0 递减,并无限重复的数字。

我到目前为止的代码似乎接近,但在第二次迭代中setInterval的我2个各自函数的调用countUp,并countDown似乎彼此发生冲突,因为显示的数字没有在预期的顺序计数......然后浏览器崩溃。

这是我的代码:

<!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>

回答by xandercoded

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

您需要将返回值捕获setInterval( ... )到一个变量中,因为它是对计时器的引用:

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);
    }
}

回答by Gerardo Lima

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

@Claude,你说得对,我提出的另一个解决方案与原始代码差别太大。这是另一种可能的解决方案,使用setInterval和切换功能:

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);
}

回答by Rocket Hazmat

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

clearInterval(this);. 你不能那样做。您需要将返回值从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);
    }       
}

回答by Fabrizio Calderan

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 #hereelement. Use always ===instead of ==

您还可以创建对#here元素的单个引用。使用始终===代替==

回答by Gerardo Lima

There are many ways to solve this problem, the following is my suggestion:

解决这个问题的方法有很多,以下是我的建议:

function onloadFunctions() {
    var count = 0;
    var delta = 1;
    var target = document.getElementById("here");
    var step = function() {
        if(count <= 0) delta =  1;
        if(count >= 9) delta = -1;
        count += delta;
        target.innerHTML = count;
        window.setTimeout(step, 500);
    }
    step ();
}

PS: it's safer to use setTimeoutthan setInteval.

PS:使用setTimeoutsetInteval.

回答by Flavio

    /** Tools */
const log = require('ololog').configure({
  locate: false
})

let count = 0
let interval__UP
let interval__DOWN

function countUp () {
  count++
  log.green('countUp(): ', count)

  if (count == 5) {
    clearInterval(interval__UP)
    interval__DOWN = setInterval(function () {
      countDown()
    }, 1000)
  }

}

function countDown () {

  count--
  log.red('countDown(): ', count)

  if (count == 0) {
    clearInterval(interval__DOWN)
    interval__UP = setInterval(function () {
      countUp()
    }, 3000)
  }
}

function start () {
  countUp()
  log.cyan('start()')
  interval__UP = setInterval(function () {
    countUp()
  }, 2000)
}

start()

Console Log shows it's working

控制台日志显示它正在工作