如何停止并重置运行中的JavaScript倒计时定时器?
嘿,我看你遇到了定时器重复运行的麻烦——每次点击按钮,旧的倒计时定时器没被停止,新的又开始跑,多个定时器同时更新页面内容,自然就乱套了。我来帮你搞定这个问题!
问题根源
你之前把定时器的引用变量x放在了setTimer函数的局部作用域里,每次调用setTimer都会创建一个全新的x变量,之前的定时器就变成了“没人管的孤儿”,根本没法被清除,所以会一直运行下去。
解决方案
我们只需要把定时器的引用提到全局作用域,每次点击按钮时先清除之前的定时器,再创建新的就行。下面是修改好的完整代码:
<!DOCTYPE HTML> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> p { text-align: center; font-size: 60px; margin-top: 0px; } </style> </head> <body> <input type='text' value='1490028077' id='timestamp'> <input type='button' id='convert' value='Convert' onclick='setTimer()'> <br><br> <span id='datetime'></span> <p id="demo"></p> <script> // 把定时器引用放到全局,这样每次点击都能拿到它 let countdownTimer = null; function setTimer() { // 先停掉之前的定时器(如果有的话) if (countdownTimer) { clearInterval(countdownTimer); } const timeSpan = convert(); const countDownDate = new Date(timeSpan).getTime(); // 创建新定时器,把引用存到全局变量里 countdownTimer = setInterval(function() { const now = new Date().getTime(); const distance = countDownDate - now; const days = Math.floor(distance / (1000 * 60 * 60 * 24)); const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); const seconds = Math.floor((distance % (1000 * 60)) / 1000); document.getElementById("demo").innerHTML = `${days}d ${hours}h ${minutes}m ${seconds}s `; if (distance < 0) { clearInterval(countdownTimer); document.getElementById("demo").innerHTML = "EXPIRED"; // 结束后把引用清空,更规范 countdownTimer = null; } }, 1000); } function convert() { const now = new Date() let secondsSinceEpoch = Math.round(now.getTime() / 1000) let unixtimestamp = document.getElementById('timestamp').value; unixtimestamp = parseInt(unixtimestamp); secondsSinceEpoch = parseInt(secondsSinceEpoch); unixtimestamp = unixtimestamp + secondsSinceEpoch; const months_arr = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; const date = new Date(unixtimestamp*1000); const year = date.getFullYear(); const month = months_arr[date.getMonth()]; const day = date.getDate(); const hours = date.getHours(); let minutes = "0" + date.getMinutes(); let seconds = "0" + date.getSeconds(); const convdataTime = `${month} ${day}, ${year} ${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}`; document.getElementById('datetime').innerHTML = convdataTime; return convdataTime; } </script> </body> </html>
关键改动说明
- 全局定时器变量:新增了全局的
countdownTimer变量,用来保存当前运行的定时器引用,这样每次点击按钮都能找到之前的定时器。 - 清除旧定时器:每次调用
setTimer时,先检查countdownTimer是否存在,如果有就用clearInterval停掉它,确保同一时间只有一个定时器在工作。 - 定时器结束后置空:当倒计时到期时,除了清除定时器,还把
countdownTimer设为null,避免后续重复清除无效的定时器(虽然clearInterval传无效ID不会报错,但这样做更严谨)。
这样修改后,你每次点击按钮都会先停止之前的倒计时,然后基于新输入的数值重新开始计算,完全符合你的需求啦!
内容的提问来源于stack exchange,提问作者חיים חדד
相关产品推荐
相关产品推荐

