Javascript 如何在同一个函数中使用setInterval()和clearInterval()
我正在尝试创建一个启动和停止计时器的函数。启动总是在单击按钮时进行,但停止可能是由于计时器停止运行或从另一个函数再次调用该函数 这就是我目前所拥有的。对于您所看到的内容,它非常适合,但我不知道如何合并clearInterval(),以便在游戏获胜时停止。正在运行的调用timerCountdown位于不同的js文件中。我读过类似问题的答案,但他们似乎都在做一些不同的事情,我不能让它为我的案件工作 我确实意识到我需要调用clearInterval(count),但我不知道如何将其合并到函数本身中Javascript 如何在同一个函数中使用setInterval()和clearInterval(),javascript,if-statement,setinterval,clearinterval,Javascript,If Statement,Setinterval,Clearinterval,我正在尝试创建一个启动和停止计时器的函数。启动总是在单击按钮时进行,但停止可能是由于计时器停止运行或从另一个函数再次调用该函数 这就是我目前所拥有的。对于您所看到的内容,它非常适合,但我不知道如何合并clearInterval(),以便在游戏获胜时停止。正在运行的调用timerCountdown位于不同的js文件中。我读过类似问题的答案,但他们似乎都在做一些不同的事情,我不能让它为我的案件工作 我确实意识到我需要调用clearInterval(count),但我不知道如何将其合并到函数本身中 c
const timerCountdown = () => {
let count = setInterval(() => {
let timeLeft = timer.innerHTML
if (timeLeft > 0) {
timer.innerHTML = timeLeft - 1
} else {
gameOverMessage()
}
}, 1000)
}
如果赢了或没有时间可用,可以使用全局变量
intervalId
并清除间隔计时器
var intervalId;
const timerCountdown = () => {
intervalId = setInterval(() => {
let timeLeft = timer.innerHTML
if (timeLeft > 0) {
timer.innerHTML = timeLeft - 1
} else {
clearInterval(intervalId);
gameOverMessage();
}
}, 1000)
},
won = () => {
clearInterval(intervalId);
// additional code
};
您需要在全局变量中推送间隔id。这样,您可以在需要时使用另一个函数来停止间隔 像
let intervalId;//全局定义“count”
让timer=document.getElementById('timer'))
常数timerStop=()=>{
clearInterval(有效期间)
}
常量timerRestart=()=>{
timerStop()
timer.innerHTML=100;
}
常量timerStart=()=>{
timerStop();//通过安全性停止计时器,例如,如果多次调用'timerStart()'
intervalId=setInterval(()=>{
让timeLeft=timer.innerHTML;
如果(+时间间隔>0){
timer.innerHTML=+timeLeft-1
}否则{
timerRestart();
gameOverMessage()
}
}, 1000)
}
100
开始
暂停
重新启动
setInterval
尽最大努力根据指定的间隔来分配回调的运行空间。问题是:在游戏中,你真正想要的是将当前世界的状态以平滑及时的方式打印到屏幕上。这与setInterval
的行为不同,后者对屏幕一无所知,并被盲目地重复调用
例如:如果您在浏览器选项卡中启动游戏的setInterval(foo,100)
,然后导航到浏览器中的另一个选项卡,等待十秒钟,然后返回游戏,您的foo
callback将被快速连续调用大约一百次,因为排队的回调被“耗尽”。您不太可能想要这种行为
这是一个更好的解决方案,因为它只在(不久之前)渲染游戏时调用-这是您想要的
在以下代码中,计时器对象由createTimer
创建。计时器具有启动
、停止
和切换
方法
start
方法记录调用它的时间并触发requestAnimationFrame
,提供一个名为tick
的回调。每次出现滴答声时,我们都会运行一些逻辑来查看要调用哪个(如果有的话)回调
如果经过的时间大于或等于计时器的持续时间
,则调用onTimeout
回调并停止计时器
如果经过的时间小于持续时间
,但大于或等于间隔
期间,则更新lastInterval
并调用onInterval
回调
否则,我们只需提示计时器的另一个滴答声
stop
方法仅使用请求动画ID来使用cancelAnimationFrame
取消计时器
函数createTimer(){
设rafId=null
函数开始({duration=10000,interval=1000,onInterval,onTimeout,onStop,startTime=performance.now(),lastInterval=startTime}){
函数勾选(now=performance.now()){
const appeased=now-startTime
如果(经过>=持续时间){
取消动画帧(rafId)
rafId=null
return-onTimeout()
}
如果((现在-上次间隔)>=间隔){
lastInterval=现在
内部({
期间
逝去
})
}
rafId=requestAnimationFrame(勾选)
}
rafId=requestAnimationFrame(勾选)
}
函数停止(){
取消动画帧(rafId)
rafId=null
返回顶部()
}
函数切换(…参数){
rafId?停止():开始(…参数)
}
常数计时器={
开始
停止
切换
}
返回计时器
}
const timer=createTimer()
const onInterval=({duration,appeased})=>console.log(`Remaining:${((duration-appeased)/1000).toFixed(0)}`)
const onTimeout=()=>console.log('超时')
const onStop=()=>console.log('手动停止')
document.getElementById('btn')。addEventListener('click',()=>timer.toggle({
在区间,
及时,
顶上
}))
切换计时器
因此需要从外部访问让计数
。(另外,setInterval
不准确)并且timeLeft
是一个字符串,而不是一个数字。您可以向我们展示您的其他函数吗?因此,如果再次调用timerCountdown
,则倒计时停止并再次开始?@epascarello-为什么setInterval不准确?的确,timeLeft是一个字符串,但它工作得很好,所以我认为没有必要将其转换为数字。由于let和const没有被提升,所以最好在之前移动timerStoptimeStart@MosèRaguzzini谢谢,我添加了一个实时演示,我移动了timerStop