JavaScript倒计时计时器无法停止循环及更新问题求助
倒计时计时器无法停止/更新的问题解决
问题描述
我用JavaScript练习倒计时计时器,需求是用户通过<input type="date">选择日期,通过onBlur属性读取日期并触发计时函数,将日期值传入函数。
计时器本身可正常运行,但存在以下问题:
- 计时器到期后,文本变为“Expired”,但仅显示一个周期(1秒)后就会再次显示原倒计时
- 更换日期时,页面会在新旧两个日期对应的计时器显示间闪烁切换
尝试过通过额外函数调用倒计时函数、设置boolean开关标记计时器已启动、在倒计时函数末尾添加If语句,以及使用clearInterval方法,均无法终止这种无限循环。观察到setInterval持续循环,clearInterval似乎并未停止计时器,存储倒计时的变量theTimer值为5。
原因分析
核心问题是每次触发userDeadlineTimer函数时,都会创建一个新的setInterval定时器,而旧的定时器没有被清除,导致多个定时器同时在后台运行,互相干扰DOM更新:
- 当计时器到期执行
clearInterval(theTimer)时,只能清除当前函数内创建的定时器,之前的旧定时器仍在运行,所以1秒后旧定时器会再次修改文本内容 - 更换日期时,新定时器启动,但旧定时器未被销毁,两个定时器交替修改页面内容,造成闪烁现象
修复后的完整代码
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Practice</title> </head> <body> <form> <input type="date" id="calander-input" onblur="userDeadlineTimer(value)" /><br /> </form> <h3>Time until date:</h3> <p id="user-deadline">0 days 0 hours 0 minutes 0 seconds</p> <script> // 全局变量存储当前定时器ID let theTimer = null; function userDeadlineTimer(value) { // 先清除之前的定时器,避免多实例运行 if (theTimer) { clearInterval(theTimer); } let userDeadline = new Date(value).getTime(); theTimer = setInterval(function() { let userReference = new Date().getTime(); let userDelta = userDeadline - userReference; let userDays = Math.floor(userDelta / (1000 * 60 * 60 * 24)); let userHours = Math.floor((userDelta % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); let userMinutes = Math.floor((userDelta % (1000 * 60 * 60)) / (1000 * 60)); let userSeconds = Math.floor((userDelta % (1000 * 60)) / 1000); if (userDelta > 0) { document.getElementById("user-deadline").textContent = `${userDays} days ${userHours} hours ${userMinutes} minutes ${userSeconds} seconds.`; } else { clearInterval(theTimer); document.getElementById("user-deadline").textContent = "Expired"; // 将定时器ID置空,避免后续误操作 theTimer = null; } }, 1000); } </script> </body> </html>
关键修改说明
- 全局存储定时器ID:将
theTimer声明为全局变量,确保每次调用计时函数时都能访问到之前创建的定时器ID - 清除旧定时器:在创建新定时器前,先执行
clearInterval(theTimer),销毁之前的定时器实例,避免多个定时器同时运行 - 优化到期逻辑:定时器到期清除后,将
theTimer置空,避免后续重复清除不存在的定时器,同时确保到期后不会有旧定时器继续修改DOM
内容的提问来源于stack exchange,提问作者Ruzzy100
相关产品推荐
相关产品推荐

