JavaScript中keydown事件内调用setInterval时clearInterval失效问题
问题根因
- 每次按下右键都会生成一个新的定时器,且新的定时器ID会直接覆盖
increaseNum变量,之前创建的定时器ID会丢失,clearInterval只能清除最后生成的那一个定时器,更早的定时器会一直在后台执行 - 全局变量
n是所有定时器共享的,当n累加到11后只会停止最后一个定时器,其余旧定时器依然会持续累加n,不会触发自身的停止逻辑
修复方案
有两种常用实现思路,按需选择即可:
方案1:加运行锁,同一时间只允许一个定时器运行
如果业务要求每次右键触发的计数是完整独立的,没跑完的时候按右键不生效可以用这个方案:
var increaseNum; var isCounting = false; // 新增运行状态锁 function endLevel() { window.clearInterval(increaseNum); isCounting = false; // 计数结束重置锁 } var n=0; window.addEventListener("keydown", (e)=>{ if(e.key == "ArrowRight" && !isCounting){ // 只有锁空闲的时候才触发 isCounting = true; n = 0; // 每次触发重新计数可以加这行,不需要的话删掉 increaseNum = setInterval(()=>{ n +=1; if(n>10){ endLevel(); } console.log(n); }, 50) } })
方案2:每次新建定时器前先清空上一个
如果业务要求连续按右键要重置当前计数重新跑,可以用这个方案:
var increaseNum; function endLevel() { window.clearInterval(increaseNum); } var n=0; window.addEventListener("keydown", (e)=>{ if(e.key == "ArrowRight"){ endLevel(); // 新建前先清掉之前的定时器 n = 0; // 重置计数,不需要的话可以删掉 increaseNum = setInterval(()=>{ n +=1; if(n>10){ endLevel(); } console.log(n); }, 50) } })
内容的提问来源于stack exchange,提问作者ar jishat
相关产品推荐
相关产品推荐

