JavaScript秒表切换浏览器标签时暂停,需改为持续计时
解决切换标签后秒表暂停的问题
问题说明
网站上的JavaScript秒表在作者切换到其他标签页时会暂停,返回页面才继续计时,需要实现切换标签后仍持续计时的效果。
问题原因
当前代码通过setTimeout每10毫秒手动累加count/second/minute来计时,但浏览器为了节省资源,会对处于后台的标签页的定时器执行频率进行限制(节流),导致定时器无法按时触发,从而出现计时暂停的现象。
解决方案
改用记录起始时间戳的方式,每次更新计时时,计算当前时间与起始时间的差值,再将差值转换为分、秒、毫秒格式。这种方式不受定时器节流影响,能保证计时准确。
修改后的完整代码
HTML部分
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="timey" style="text-align: center;direction: ltr !important;font-size: 0px !important;font-size: 0.01px !important;visibility: hidden;"> <span class="digit" id="min">00</span> <span class="txt">:</span> <span class="digit" id="sec">00</span> <span class="txt">:</span> <span class="digit" id="count">00</span> </div> <div id="buttons" style="text-align: center;"> <button type="button" class="button" id="start">start</button> <button type="button" class="button" id="stop" style="display: none;">stop</button> <button type="button" class="button" id="reset">reset</button> </div> <input type="text" id="acf-field_651d01208c082" name="acf[field_651d01208c082]" placeholder="00:00:00" readonly="">
CSS部分
#acf-field_651d01208c082 {cursor: help;text-align: center;font-family: Vazirmatn UI, sans-serif !important;border: 0px;font-size: 19px;letter-spacing: 4px;background: transparent !important;background: #fff0 !important;} #buttons #start {background: #4CAF50;color: #FFF;border: 1px solid #4CAF50;} #buttons #start:hover {background: #409743;color: #FFF;border: 1px solid #4CAF50;} #buttons #stop {display:none;background: #e73e77;color: #FFF;border: 1px solid #e73e77;} #buttons #stop:hover {background: #c13b68;color: #FFF;border: 1px solid #e73e77;}
JavaScript部分
let startBtn = document.getElementById('start'); let stopBtn = document.getElementById('stop'); let resetBtn = document.getElementById('reset'); // 计时相关变量 let timer = null; let startTime = 0; let elapsedTime = 0; window.onload = function() { document.getElementById('stop').style.display = 'none'; }; startBtn.addEventListener('click', function () { // 如果是继续计时,基于已流逝时间重新计算起始点 startTime = Date.now() - elapsedTime; timer = setInterval(updateStopWatch, 10); document.getElementById('stop').style.display = 'inline'; document.getElementById('start').style.display = 'none'; document.getElementById('start').innerHTML = "Continue"; }); stopBtn.addEventListener('click', function () { clearInterval(timer); timer = null; // 记录当前已流逝的总时间 elapsedTime = Date.now() - startTime; document.getElementById('start').style.display = 'inline'; document.getElementById('stop').style.display = 'none'; }); resetBtn.addEventListener('click', function () { clearInterval(timer); timer = null; startTime = 0; elapsedTime = 0; document.getElementById('min').innerHTML = "00"; document.getElementById('sec').innerHTML = "00"; document.getElementById('count').innerHTML = "00"; document.getElementById('acf-field_651d01208c082').value = "00:00:00"; document.getElementById('start').style.display = 'inline'; document.getElementById('stop').style.display = 'none'; document.getElementById('start').innerHTML = "start"; }); function updateStopWatch() { // 计算从起始到现在的总流逝毫秒数 const totalMilliseconds = Date.now() - startTime; // 转换为分、秒、百分之一秒(对应原count的10毫秒单位) const minute = Math.floor(totalMilliseconds / (60 * 1000)); const second = Math.floor((totalMilliseconds % (60 * 1000)) / 1000); const count = Math.floor((totalMilliseconds % 1000) / 10); // 格式化数字为两位数 const minString = minute < 10 ? `0${minute}` : `${minute}`; const secString = second < 10 ? `0${second}` : `${second}`; const countString = count < 10 ? `0${count}` : `${count}`; // 更新页面显示和输入框值 document.getElementById('min').innerHTML = minString; document.getElementById('sec').innerHTML = secString; document.getElementById('count').innerHTML = countString; document.getElementById('acf-field_651d01208c082').value = `${minString}:${secString}:${countString}`; } jQuery('#acf-group_651d0120348fc').insertAfter('#submitdiv');
关键改动说明
- 用
startTime(计时起始时间戳)和elapsedTime(暂停时已流逝的时间)替代原手动累加的计数变量,确保计时基于真实时间差计算。 - 切换标签时,即使定时器被节流,重新回到页面后会通过当前时间与起始时间的差值直接计算准确时长,不会出现计时断层。
- 暂停时保存已流逝时间,继续计时时基于该时间重新校准起始点,保证计时连贯性。
内容的提问来源于stack exchange,提问作者Ahmad Karimi
相关产品推荐
相关产品推荐

