StopWatch点击停止按钮重启后分钟计时异常问题排查
StopWatch暂停重启后分钟计时失效问题排查与修复
问题分析
点击Stop按钮暂停后等待片刻,再点击Start重启,秒计时正常但分钟计时完全失效,核心原因有两点:
- 独立定时器导致计时错位:分钟/小时使用独立的
setInterval,暂停重启后定时器会从重启时刻重新倒计时,无法基于之前累计的时间继续计算,且多定时器的时间误差会逐步累积,导致计时不同步。 - DOM创建逻辑冗余:原代码通过变量
s控制分钟元素的添加,首次启动后s被设为false,后续重启时无法重新挂载元素(非核心失效原因,但会导致显示异常)。 - 小时定时器时间间隔错误:原代码中小时定时器的间隔写为
60000(1分钟),而非正确的3600000(1小时)。
修复方案
放弃分钟和小时的独立定时器,改为基于秒的更新联动计算分钟和小时,确保所有计时逻辑完全同步:
- 每次秒数更新时判断是否达到60,若达到则重置秒数并累加分钟
- 分钟达到60时重置并累加小时
- 提前创建好分钟、小时的DOM元素并默认隐藏,启动时按需显示,避免重复创建DOM的逻辑问题
修复后的完整代码
HTML
<body> <main> <div> <h1>STOP WATCH</h1> <div id="time"> <!-- 提前创建小时、分钟容器,默认隐藏 --> <h3 class="time_s_m_h" id="hourContainer" style="display:none"> <span id="hour" class="value">0</span> <span class="sigin">H</span> </h3> <h3 class="time_s_m_h" id="minContainer" style="display:none"> <span id="min" class="value">0</span> <span class="sigin">M</span> </h3> <h3 class="time_s_m_h"> <span id="second" class="value">0</span> <span class="sigin">S</span> </h3> <h3 id="h3"> <span id="milisecond" class="sigin">00</span> </h3> </div> </div> <div id="btnDiv"> <button id="start">Start</button> <button id="stop">Stop</button> <button id="reset">Reset</button> </div> </main> <script src="app.js"></script> </body>
CSS
*{ margin: 0px; padding: 0px; box-sizing: border-box; font-family: Arial, Helvetica, sans-serif; color: white; } main{ width: 100%; height: 500px; background-color: #FEA600; display: flex; flex-direction: column; align-items: center; } main div:first-child{ margin-top: 20px; } main div:first-child h1, main div:first-child h2,main div:first-child h3{ font-size: 4rem; font-weight: 100; text-align: center; margin-top: 20px; } main div:first-child #time{ display: flex; align-items: center; justify-content: center; width: 100%; } main div:first-child #time .time_s_m_h{ display: flex; align-items: flex-end; justify-content: center; width: 100px; margin: 5px; } main div:first-child h3 .sigin{ font-size: 2rem; } main div:first-child h3 #milisecond{ display: inline-block; width: 50px; } main div:last-child{ display: flex; } main div:last-child button{ padding: 20px; width: 150px; background-color: #FEA600; font-size: 25px; margin: 10px; border:1px solid #ffffff; cursor: pointer; } #stop,#reset{ display: none; }
JavaScript
let start = document.getElementById("start"); let stop = document.getElementById("stop"); let reset = document.getElementById("reset"); let milisecond = document.getElementById("milisecond"); let second = document.getElementById("second"); let min = document.getElementById("min"); let hour = document.getElementById("hour"); let minContainer = document.getElementById("minContainer"); let hourContainer = document.getElementById("hourContainer"); let secStart = 0; let miliSecStart = 0; let minStart = 0; let hourStart = 0; let miliTimer, secTimer; start.addEventListener("click", function () { reset.style.display = "block"; stop.style.display = "block"; start.style.display = "none"; // 毫秒计时 miliTimer = setInterval(() => { miliSecStart++; milisecond.innerText = miliSecStart.toString().padStart(2, "0"); if (miliSecStart === 99) { miliSecStart = 0; } }, 10); // 秒计时,联动分钟与小时 secTimer = setInterval(() => { secStart++; second.innerText = secStart; // 秒数到60,重置并累加分钟 if (secStart === 60) { secStart = 0; second.innerText = "0"; minStart++; min.innerText = minStart; minContainer.style.display = "flex"; // 分钟到60,重置并累加小时 if (minStart === 60) { minStart = 0; min.innerText = "0"; hourStart++; hour.innerText = hourStart; hourContainer.style.display = "flex"; // 小时到24重置 if (hourStart === 24) { hourStart = 0; hour.innerText = "0"; } } } }, 1000); }); stop.addEventListener("click", function () { start.style.display = "block"; stop.style.display = "none"; clearInterval(miliTimer); clearInterval(secTimer); }); reset.addEventListener("click", function () { start.style.display = "block"; stop.style.display = "none"; clearInterval(miliTimer); clearInterval(secTimer); // 重置所有计时值与显示状态 miliSecStart = 0; milisecond.innerText = "00"; secStart = 0; second.innerText = "0"; minStart = 0; min.innerText = "0"; minContainer.style.display = "none"; hourStart = 0; hour.innerText = "0"; hourContainer.style.display = "none"; });
内容的提问来源于stack exchange,提问作者aryan raj
相关产品推荐
相关产品推荐

