为什么JS倒计时脚本中超时替换open文本为close的代码不生效
问题根因
- 到期逻辑的位置完全错了。你写的文本替换、倒计时清零代码,被放在了
setInterval定时器的外部,属于页面加载时就跑的同步逻辑,根本不会在倒计时真正到期时触发。而真正的到期判断分支(定时器回调里distance <0的代码块),只做了清除定时器的操作,半行状态更新的代码都没有,自然不会在倒计时结束时改文本。 - 判断条件完全错位。你用来触发到期逻辑的if判断,用的是开头定义的那几个全局时间常量(
second=1000、minute=60*1000这类),这些是固定不变的换算基准,值永远远大于10,根本不是你想判断的「剩余天/时/分/秒的动态值」。而真正算出来的days、hours这些剩余时间变量,是定义在定时器回调里的局部变量,在全局作用域根本无法访问,整个判断从一开始就和预期逻辑没关系。 - 文本替换的方式低效且有风险。你靠重写整个
document.body.innerHTML来改文字,不仅会触发页面全量重绘,性能差,还可能丢失之前绑定的事件监听,甚至误替换页面其他位置的相同文本。
修复方法
- 把所有到期后的处理逻辑(倒计时数字清零、状态文本替换)挪到定时器回调里的
distance <0分支里,在清除定时器之后执行。 - 删掉全局作用域里那段逻辑错误的if-else代码,它根本不产生正确作用。
- 你HTML里本来就给状态段落加了id是
timerout,直接通过这个id拿到节点改innerText就行,没必要动整个body的HTML。
修复后的核心JS代码如下:
const second = 1000, minute = second * 60, hour = minute * 60, day = hour * 24; // 替换成实际需要的目标时间即可 let countDown = new Date('February 03, 2021 20:35:00').getTime(), x = setInterval(function() { let now = new Date().getTime(), distance = countDown - now; // 倒计时到期的所有处理逻辑都放在这个分支里 if (distance < 0) { clearInterval(x); // 所有倒计时位清零 document.getElementById('days').innerText = '00'; document.getElementById('hours').innerText = '00'; document.getElementById('minutes').innerText = '00'; document.getElementById('seconds').innerText = '00'; // 直接改状态文本,无需操作整个页面HTML document.getElementById('timerout').innerText = 'close'; return; } // 正常运行时的剩余时间计算、DOM更新 var days = Math.floor(distance / (day)); var hours = Math.floor((distance % (day)) / (hour)); var minutes = Math.floor((distance % (hour)) / (minute)); var seconds = Math.floor((distance % (minute)) / second); document.getElementById('days').innerText = (days < 10) ? '0' + days : days; document.getElementById('hours').innerText = (hours < 10) ? '0' + hours : hours; document.getElementById('minutes').innerText = (minutes < 10) ? '0' + minutes : minutes; document.getElementById('seconds').innerText = (seconds < 10) ? '0' + seconds : seconds; }, second)
内容的提问来源于stack exchange,提问作者user13851719
相关产品推荐
相关产品推荐

