两个独立Timer异常:点击启动按钮后同时运行,求排查解决
双计时器同步启动问题排查与修复
问题描述
编写了两个独立计时器,但点击任意一个启动按钮时,两个计时器都会同时开始运行,尝试条件判断无效,需排查修复。
原代码
JavaScript
const res = document.getElementById('res'), btnStart = document.getElementById('start'), btnStop = document.getElementById('stop'); const res1 = document.getElementById('res1'), btnStart1 = document.getElementById('start1'), btnStop1 = document.getElementById('stop1'); function getCounter(el, startBtn, stopBtn) { let sec = 0; let min = 0; let hours = 0; let interval; let isAvtive = false; function updateCounter() { sec++; if (sec === 60) { min++; sec = 0; } if (min === 60) { hours++; min = 0; } if (hours === 24) { hours = 0; } el.textContent = sec; if (btnStart) { res.textContent = `${hours.toString().padStart(2,0)}:${min.toString().padStart(2,0)}:${sec.toString().padStart(2,0)}`; } if (btnStart1) { res1.textContent = `${hours.toString().padStart(2,0)}:${min.toString().padStart(2,0)}:${sec.toString().padStart(2,0)}`; } } startBtn.addEventListener('click', function() { if (btnStart) interval = setInterval(updateCounter, 1000); }); stopBtn.addEventListener("click", function() { if (interval) { clearInterval(interval) interval = null; } }) } getCounter(res, btnStart, btnStop); getCounter(res1, btnStart1, btnStop1);
HTML
<input type="button" value="start" id="start" /> <input type="button" value="stop" id="stop" /> <span id="res"></span> <br/> <input type="button" value="start1" id="start1" /> <input type="button" value="stop1" id="stop1" /> <span id="res1"></span>
问题排查
- 全局DOM硬编码干扰:
updateCounter函数直接操作全局的res和res1元素,导致每个计时器的回调都会同时修改两个显示区域,造成"同步运行"的错觉。 - 启动逻辑判断错误:启动按钮的判断使用全局变量
btnStart,而非当前实例的startBtn参数,导致两个计时器实例都会执行同一启动逻辑。 - 未控制重复启动:定义了
isAvtive状态但未使用,无法防止多次点击启动按钮创建叠加定时器。
修复方案
修改getCounter函数,让每个计时器实例完全独立,仅依赖传入参数和自身内部状态:
function getCounter(el, startBtn, stopBtn) { let sec = 0; let min = 0; let hours = 0; let interval = null; let isActive = false; function updateCounter() { sec++; if (sec === 60) { min++; sec = 0; } if (min === 60) { hours++; min = 0; } if (hours === 24) { hours = 0; } // 仅更新当前实例对应的显示元素 el.textContent = `${hours.toString().padStart(2,0)}:${min.toString().padStart(2,0)}:${sec.toString().padStart(2,0)}`; } startBtn.addEventListener('click', function() { // 防止重复启动 if (!isActive) { isActive = true; interval = setInterval(updateCounter, 1000); } }); stopBtn.addEventListener("click", function() { if (interval) { clearInterval(interval); interval = null; isActive = false; } }); } // 初始化两个独立计时器 getCounter(document.getElementById('res'), document.getElementById('start'), document.getElementById('stop')); getCounter(document.getElementById('res1'), document.getElementById('start1'), document.getElementById('stop1'));
修改说明
- 移除全局DOM变量依赖,仅通过传入的
el参数更新当前计时器的显示内容 - 使用
isActive状态控制计时器启停,避免多次点击启动按钮创建叠加定时器 - 每个计时器实例的
sec、min、hours、interval均为独立局部变量,互相无干扰 - 简化启动逻辑,基于当前实例状态处理,不再依赖全局按钮变量判断
内容的提问来源于stack exchange,提问作者John Shevchenko
相关产品推荐
相关产品推荐

