clearTimeout 不工作:参数未定义(即使它是在全局范围内定义的)
clearTimeout not working: parameter undefined(even though it's defined in the global scope)
我的 setTimeout() 函数有效,但我的 clearTimeout() 无效。即使我有一个 'if' 语句应该 运行 clearTimeout 函数,一旦我的变量 'secs' 小于 0,计时器就会继续倒计时为负数。当我在控制台中输入我的变量名 '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);
}
添加一个条件来调用递归函数,如下所示。
if (secs < 0) {
secs = secsInput;
}
//recurring function
countDown = setTimeout('startTimer('+secs+',"'+elem+'")', 1000);
对于倒数计时器,我建议改用 setInterval
和 clearInterval
。 setInterval
会为您重复运行回调函数。它可能看起来像这样:
let countdown;
function startTimer(secs, elem) {
countdown = setInterval(function(){
t = $(elem);
t.innerHTML = "00:" + secs;
secs--
if (secs < 0) {
clearInterval(countdown);
}
}, 1000);
}
在你的情况下,使用 setInterval
和 clearInterval
更方便。
要保留 setTimeout
和 clearTimeout
功能,您应该在 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);
}
当您调用 clearTimeout(countDown)
时,countDown
指的是 previous 超时,它已经超时了。它不会阻止尚未开始的人。你可以不重新设置超时,比如
if(!/*finished*/) setTimeout(startTimer, 1000, secs, elem);
所以我认为有 4 个事件必须由计时器处理:
- 测验开始
- 测验结束
- 计时器用完
- 玩家回答问题
这可以通过一个返回带有一些选项的对象的函数来解决。
createTimer可以用来设置定时器的参数。
点 1. 将是 timer.start() --> 将使用参数
启动计时器
第 3 点可以通过计时器用完时将调用的回调来解决 --> createTimer(5,'display', ()=>{ // your code goes here })
第 2 点可以通过 --> timer.stop()
实现
第 4 点需要在没有 运行 out timer.reset()
的情况下重置计时器
此外,间隔不在全局范围内,因此您可以有多个具有不同设置的计时器,并且它们不会相互干扰
// 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()
我的 setTimeout() 函数有效,但我的 clearTimeout() 无效。即使我有一个 'if' 语句应该 运行 clearTimeout 函数,一旦我的变量 'secs' 小于 0,计时器就会继续倒计时为负数。当我在控制台中输入我的变量名 '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);
}
添加一个条件来调用递归函数,如下所示。
if (secs < 0) {
secs = secsInput;
}
//recurring function
countDown = setTimeout('startTimer('+secs+',"'+elem+'")', 1000);
对于倒数计时器,我建议改用 setInterval
和 clearInterval
。 setInterval
会为您重复运行回调函数。它可能看起来像这样:
let countdown;
function startTimer(secs, elem) {
countdown = setInterval(function(){
t = $(elem);
t.innerHTML = "00:" + secs;
secs--
if (secs < 0) {
clearInterval(countdown);
}
}, 1000);
}
在你的情况下,使用 setInterval
和 clearInterval
更方便。
要保留 setTimeout
和 clearTimeout
功能,您应该在 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);
}
当您调用 clearTimeout(countDown)
时,countDown
指的是 previous 超时,它已经超时了。它不会阻止尚未开始的人。你可以不重新设置超时,比如
if(!/*finished*/) setTimeout(startTimer, 1000, secs, elem);
所以我认为有 4 个事件必须由计时器处理:
- 测验开始
- 测验结束
- 计时器用完
- 玩家回答问题
这可以通过一个返回带有一些选项的对象的函数来解决。 createTimer可以用来设置定时器的参数。
点 1. 将是 timer.start() --> 将使用参数
启动计时器第 3 点可以通过计时器用完时将调用的回调来解决 --> createTimer(5,'display', ()=>{ // your code goes here })
第 2 点可以通过 --> timer.stop()
实现第 4 点需要在没有 运行 out timer.reset()
的情况下重置计时器此外,间隔不在全局范围内,因此您可以有多个具有不同设置的计时器,并且它们不会相互干扰
// 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()