Javascript函数内定时器调用clearTimeout不生效、倒计时倍速问题求助
定时器倍速问题解决方案
核心原因
AJAX重载包含定时器代码的DIV时,旧的定时器实例未被清除,同时新的定时器代码被重复执行,生成了多个并行运行的定时器实例,每秒会多次触发倒计时减1逻辑,最终出现双倍/多倍速运行的问题。
排查方向
- 定时器ID需要存储在全局作用域(或不会被AJAX重载覆盖的上层作用域)中,你之前将定时器ID存在局部变量里,AJAX刷新后变量引用丢失,自然无法清除旧定时器。
- 每次执行定时器回调、启动新定时器之前,先清空上一次的定时器实例,避免重复生成。
- 触发AJAX重载DIV的操作执行前,主动调用
clearTimeout清除已有定时器,同时重置倒计时变量的初始值,避免旧值干扰。 - 不要使用字符串形式的回调参数调用
setTimeout(比如setTimeout('timer1()',1000)),该写法存在作用域风险,直接传函数引用setTimeout(timer1, 1000)更稳妥。
修正后代码示例
// 将定时器ID挂载到全局window对象,避免被AJAX刷新的局部作用域覆盖 window.timer1Id = null var var1 = 60; // 倒计时秒数 function timer1() { // 执行逻辑前先清空上一次的定时器,避免重复实例 if (window.timer1Id) { clearTimeout(window.timer1Id) window.timer1Id = null } if (var1 > 0) { var1 = var1 - 1; } else { var1 = "<font color=\"#90ee90\">GO</font>"; } var countdown = document.getElementById ? document.getElementById("timer1") : (document.all ? document.all["timer1"] : ""); if (countdown) { countdown.innerHTML = var1 + " "; // 将新生成的定时器ID存储到全局 window.timer1Id = setTimeout(timer1, 1000); } } // 首次启动前先清空可能存在的旧定时器 if (window.timer1Id) { clearTimeout(window.timer1Id) } // 重置倒计时初始值,避免AJAX重载后沿用旧值运行 var1 = 60 timer1();
额外注意
每次触发AJAX重载该DIV的逻辑执行前,先主动运行clearTimeout(window.timer1Id)清理旧定时器,再加载新的DIV内容,可彻底避免多定时器并行的问题。
内容的提问来源于stack exchange,提问作者tom savage
相关产品推荐
相关产品推荐

