JS事件e/this绑定 多计时器对应点击按钮独立更新问题求解
问题根因
你当前代码所有计时器同步更新、无法独立运行的核心问题有3个:
- 所有计时模块共用全局的
sec/min/hour/newP/timer变量,每次新建计时模块都会覆盖之前的变量引用,最终更新时永远只会操作最后一次创建的p元素 - 时间进位逻辑里把赋值符号
=错写为全等比较===,秒、分进位时不会正常归零 setInterval调用startTimer时没有传入对应模块的上下文,即使传了事件对象e,全局变量共享的问题没解决也无法实现独立计时
实现方案
你的思路方向是对的,但不需要每次点击都通过event.target查找父元素关联对应p标签,更简单的实现方式是给每个计时模块维护独立的作用域,把每个模块对应的时间显示元素、计时值、定时器ID都存在独立作用域中,从根源上避免变量共享冲突。
修正后完整代码
HTML部分
<h1>Testing</h1> <button id="test" class="test">CREATE DIV</button> <section id="textArea"> </section>
JavaScript部分
// 绑定创建计时模块按钮的事件 const createBtn = document.getElementById("test"); const container = document.getElementById("textArea"); createBtn.addEventListener("click", createTimerUnit); function createTimerUnit() { // 每个计时单元独立的DOM引用,存在当前函数作用域,不与其他单元共享 const timeShow = document.createElement("p"); timeShow.classList.add("myFont"); timeShow.textContent = "00:00:00"; container.appendChild(timeShow); const startBtn = document.createElement("button"); startBtn.textContent = "START"; container.appendChild(startBtn); // 每个计时单元独立的计时状态、定时器ID let sec = 0; let min = 0; let hour = 0; let timer = null; startBtn.addEventListener("click", function() { // 防止重复点击启动多个定时器 if (timer) return; timer = setInterval(function() { sec++; if (sec === 60) { sec = 0; min++; } if (min === 60) { min = 0; hour++; } // 格式化时间 const secFormat = sec < 10 ? `0${sec}` : sec; const minFormat = min < 10 ? `0${min}` : min; const hourFormat = hour < 10 ? `0${hour}` : hour; // 仅更新当前单元对应的时间显示 timeShow.textContent = `${hourFormat} : ${minFormat} : ${secFormat}`; }, 1000) }) }
关键改动说明
- 移除了所有全局的计时状态、DOM引用变量,每个计时模块的状态完全独立,新建模块不会覆盖旧模块的引用
- 不需要依赖事件对象查找关联DOM:创建p标签和按钮时就在同一作用域,直接持有对应显示元素的引用,比每次触发事件再遍历DOM查找关联元素性能更好
- 修正了时间进位的符号错误,补了重复点击启动定时器的拦截逻辑
内容的提问来源于stack exchange,提问作者madQuestions
相关产品推荐
相关产品推荐

