JS中clearInterval无法停止setInterval计时器怎么办?
问题原因
- 定时器ID作用域错误:
refreshId是代码逻辑分支内的局部变量,执行else分支调用clearInterval时,无法获取到对应定时器的有效ID,导致清除失败。 - 存储值被意外覆盖:定时器回调中直接将
v[ele.id]赋值为对象,原本存储的按钮数值被覆盖,后续点击的数值循环、定时器判断逻辑全部失效,就会出现打印object的异常内容。
修复代码
HTML部分(原有逻辑不变)
<button id="b1">0</button> <button id="b2">0</button> <button id="b3">0</button>
JS部分(修复后)
$("button").click(function () { buttonVal(this); }); // 拆分存储对象,分别存按钮数值和对应定时器ID,避免互相覆盖 var btnVal = {}; var timerMap = {}; function buttonVal(ele) { const id = ele.id; // 每次点击先清除当前按钮已有定时器,避免重复启动 if (timerMap[id]) { clearInterval(timerMap[id]); timerMap[id] = null; } // 0-3循环逻辑 btnVal[id] = typeof btnVal[id] === "undefined" ? 0 : btnVal[id] === 3 ? 0 : btnVal[id] + 1; // 更新按钮显示的数值 ele.innerHTML = btnVal[id]; // 数值为2时启动定时器 if(btnVal[id] === 2) { timerMap[id] = setInterval(function(){ ele.innerHTML = Date.now(); }, 2000); } }
修复说明
- 拆分独立存储对象,数值和定时器ID分开存储,不会出现数值被覆盖的问题
- 定时器ID全局存储,调用
clearInterval时可以获取到正确的ID,定时器可以正常清除 - 每次点击先清定时器,避免同一个按钮启动多个定时器导致逻辑混乱
- 去掉冗余的switch分支,简化了代码逻辑
内容的提问来源于stack exchange,提问作者shada
相关产品推荐
相关产品推荐

