clearTimeout不起作用:参数未定义(即使已在全局范围中定义)

时间:2019-12-25 13:46:35

标签: javascript cleartimeout

我的setTimeout()函数可以工作,但是我的clearTimeout()无法工作。即使我有一个'if'语句,一旦我的变量'secs'小于0,它就应该运行clearTimeout函数,但计时器仍会递减计数为负数。当我在控制台中输入变量名“ secs”时,即使定义为setTimeout调用的函数中的参数,也无法定义。我不知道我在做什么错。有人可以帮忙吗?

我的完整代码在https://codepen.io/Rburrage/pen/qBEjXmx

这是JavaScript片段:

function startTimer(secs, elem) {
    t = $(elem);
    t.innerHTML = "00:" + secs;

    if(secs<0) {
        clearTimeout(countDown);
    }
    secs--;
    //recurring function
    countDown = setTimeout('startTimer('+secs+',"'+elem+'")', 1000);

}

5 个答案:

答案 0 :(得分:0)

为调用递归函数添加条件,如下所示。

if (secs < 0) {

   secs = secsInput;
 }

   //recurring function
    countDown = setTimeout('startTimer('+secs+',"'+elem+'")', 1000);

答案 1 :(得分:0)

对于倒数计时器,我建议改为使用setIntervalclearIntervalsetInterval将为您反复运行回调函数。可能看起来像这样:

let countdown;

function startTimer(secs, elem) {
  countdown = setInterval(function(){
    t = $(elem);
    t.innerHTML = "00:" + secs;

    secs--
    if (secs < 0) {
      clearInterval(countdown);
    }
  }, 1000);
}

答案 2 :(得分:0)

对于您而言,使用setIntervalclearInterval更方便。

要保留setTimeoutclearTimeout函数,应在if语句中添加return

function startTimer(secs, elem) {
    t = $(elem);
    t.innerHTML = "00:" + secs;

    if(secs<0) {
        clearTimeout(countDown);
        return;
    }
    secs--;
    //recurring function
    countDown = setTimeout('startTimer('+secs+',"'+elem+'")', 1000);

}

答案 3 :(得分:0)

在您致电clearTimeout(countDown)时,countDown指的是上一个超时,该超时已超时。它不会停止一个尚未开始的动作。您无法重新设置超时时间,例如

 if(!/*finished*/) setTimeout(startTimer, 1000, secs, elem);

答案 4 :(得分:0)

因此,我认为有4个事件必须由计时器处理:

  1. 测验开始
  2. 测验结束
  3. 计时器用完
  4. 玩家回答了一个问题

这可以通过函数返回带有一些选项的对象来解决。 createTimer可用于设置计时器的参数。

第1点将是timer.start()->将使用参数启动计时器

第3点可以通过如果计时器用完时将被调用的回调来解决-> createTimer(5,'display', ()=>{ // your code goes here })

第2点可以通过-> timer.stop()

实现

当需要在不耗尽timer.reset()的情况下重置计时器时,需要第4点。

进一步的时间间隔不在全局范围内,因此您可以有多个具有不同设置的计时器,并且它们不会互相干扰

// function for creating the timer
function createTimer(seconds, cssSelector, callbackOnTimeout) {
    // interval the timer is running
    let interval;
    // the html node where innerText will be set
    const display = document.getElementById(cssSelector)
    // original seconds passt to createTimer needed for restart
    const initSec = seconds

    // starting or continuing the interval
    function start() {

        // setting interval to the active interval
        interval = setInterval(() => {

            display.innerText = `00:${seconds}`;

            --seconds;
            if (seconds < 0) {
                // calling restart and callback to restart
                callbackOnTimeout()
                restart()
            }
        }, 1000);

    }

    // just stopping but not resetting so calling start will continue the timer
    // player takes a break
    function stop(){
        clearInterval(interval)
    }

    // opted for a restart and not only a reset since it seemed more appropriate for your problem
    function restart(){
        clearInterval(interval)
        seconds = initSec
        start()
    }
    // returning the object with the functions
    return {
        start: start,
        stop:   stop,
        restart:  restart
    }
}

// example for creating a timer
const timer1 = createTimer(5,'display',()=>{
    console.log(`you where to slow ohhh...`)
})

// calling the timer
timer1.start()