如何停止并恢复interval而非清除后重新调用?
实现可暂停/恢复的精准计数器
嘿,你遇到的问题其实是setInterval的常见局限——它没办法追踪暂停时的剩余触发时间,一旦用clearInterval清除,下次重启只能从零开始计时。要实现暂停后从剩余时间继续的效果,我们可以用setTimeout模拟setInterval,同时通过时间戳记录剩余时长,具体方案如下:
核心思路
setInterval是固定间隔重复触发,但没有内置的剩余时间记录;而setTimeout是单次触发,我们可以在每次触发后手动安排下一次,同时记录上一次触发的时间戳。当需要暂停时,计算当前距离下一次触发还剩多少时间,恢复时就用这个剩余时间启动下一次setTimeout,就能实现无缝衔接。
修改后的完整代码
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button type="button" id="testing">停止计数</button> <p class="text3"></p> <script> $(function() { // 获取DOM元素 const testingB = $('#testing'); const testingBox = $('.text3'); // 计数器变量 let counter = 0; // 计时器核心变量 let timerId = null; let lastTime = Date.now(); // 上一次计数器增加的时间戳 const interval = 1000; // 计数间隔(1秒) let isRunning = true; // 当前运行状态标记 let remainingTime = interval; // 暂停时的剩余触发时间 // 实时更新计数器显示(保留你原有的高频刷新逻辑) setInterval(() => { testingBox.text(counter); }, 1); // 核心计数触发函数 function runTimer() { counter++; lastTime = Date.now(); // 安排下一次计数触发 timerId = setTimeout(runTimer, interval); } // 暂停/恢复切换函数 function toggleTimer() { if (isRunning) { // 暂停操作:清除当前计时器,计算剩余时间 clearTimeout(timerId); const elapsedTime = Date.now() - lastTime; remainingTime = interval - elapsedTime; isRunning = false; testingB.text('恢复计数'); } else { // 恢复操作:用剩余时间启动下一次计数 timerId = setTimeout(runTimer, remainingTime); isRunning = true; testingB.text('停止计数'); } } // 初始化启动计时器 runTimer(); // 绑定按钮点击事件 testingB.on('click', toggleTimer); }); </script>
关键逻辑说明
- 实时显示:保留了你原有的1ms间隔刷新显示,确保计数器变化能立刻同步到页面。
- 时间戳追踪:
lastTime记录每次计数器递增的时间点,暂停时通过Date.now() - lastTime计算已流逝的时间,进而得到剩余的触发间隔remainingTime。 - 状态切换:点击按钮时根据
isRunning标记执行对应逻辑:- 暂停:清除当前
setTimeout,计算剩余时间并更新按钮文字。 - 恢复:用剩余时间启动新的
setTimeout,让计数器从暂停时的剩余节点继续触发。
- 暂停:清除当前
这样修改后,就能实现你想要的效果——比如计数器在触发后过了300ms被暂停,恢复时会等待700ms后再递增计数,完全贴合需求~
内容的提问来源于stack exchange,提问作者Jesús Palmera
相关产品推荐
相关产品推荐

