JavaScript中clearInterval无法清除定时器问题求助
问题分析与解决方案
问题根源:变量x的作用域不匹配。你在if块内部用var x声明了定时器ID,而resetTimerAndSaveExam函数处于外部作用域,无法访问到这个局部的x,导致clearInterval(x)实际上是在清除一个undefined的标识符,自然无法终止定时器。
以下是几种可行的解决方法:
方法一:将定时器ID提升到全局作用域声明
把x的声明移到全局作用域,让resetTimerAndSaveExam能直接访问:
// 全局作用域声明定时器变量 var x; function resetTimerAndSaveExam(){ clearInterval(x); // 可选:清除本地存储的倒计时记录 localStorage.removeItem('saved_countdown'); // 可选:更新UI状态 $('#timeRemaining').css('color', 'red').html("INTERROTTO"); } if($('#exerciseTipology').val() === "exam"){ var totalMinutes = $('#totalMinutes').val(); var time = 60 * totalMinutes; var saved_countdown = localStorage.getItem('saved_countdown'); if(saved_countdown == null) { var new_countdown = new Date().getTime() + time * 1000; time = new_countdown; localStorage.setItem('saved_countdown', new_countdown); } else { time = saved_countdown; } // 赋值给全局变量x x = setInterval(() => { var now = new Date().getTime(); var distance = time - now; var timeLeft = millisToMinutesAndSeconds(distance) if ($('#timeRemaining').length){ document.getElementById("timeRemaining").innerHTML = timeLeft; } if (distance/1000 <= 0) { clearInterval(x); localStorage.removeItem('saved_countdown'); $('#timeRemaining').css('color', 'red'); $('#timeRemaining').html("CONCLUSO"); location.href = URL + "teoria/saveExam"; } }, 1000); }
方法二:将函数与定时器放在同一作用域(推荐)
如果你的代码原本包裹在DOM就绪回调(比如$(function(){...}))里,把resetTimerAndSaveExam也移到同一个作用域内,用let实现块级作用域,避免污染全局:
$(function(){ let x; // 块级作用域变量,更安全 function resetTimerAndSaveExam(){ clearInterval(x); localStorage.removeItem('saved_countdown'); $('#timeRemaining').css('color', 'red').html("INTERROTTO"); } if($('#exerciseTipology').val() === "exam"){ var totalMinutes = $('#totalMinutes').val(); var time = 60 * totalMinutes; var saved_countdown = localStorage.getItem('saved_countdown'); if(saved_countdown == null) { var new_countdown = new Date().getTime() + time * 1000; time = new_countdown; localStorage.setItem('saved_countdown', new_countdown); } else { time = saved_countdown; } x = setInterval(() => { var now = new Date().getTime(); var distance = time - now; var timeLeft = millisToMinutesAndSeconds(distance) if ($('#timeRemaining').length){ document.getElementById("timeRemaining").innerHTML = timeLeft; } if (distance/1000 <= 0) { clearInterval(x); localStorage.removeItem('saved_countdown'); $('#timeRemaining').css('color', 'red'); $('#timeRemaining').html("CONCLUSO"); location.href = URL + "teoria/saveExam"; } }, 1000); } // 绑定按钮点击事件(需替换为你的按钮ID) $('#stopExamBtn').click(resetTimerAndSaveExam); });
方法三:用DOM自定义属性存储定时器ID
不需要依赖作用域,把定时器ID存在DOM元素的自定义属性中:
function resetTimerAndSaveExam(){ // 从DOM元素读取定时器ID const timerId = $('#timeRemaining').data('timerId'); clearInterval(timerId); localStorage.removeItem('saved_countdown'); $('#timeRemaining').css('color', 'red').html("INTERROTTO"); } if($('#exerciseTipology').val() === "exam"){ var totalMinutes = $('#totalMinutes').val(); var time = 60 * totalMinutes; var saved_countdown = localStorage.getItem('saved_countdown'); if(saved_countdown == null) { var new_countdown = new Date().getTime() + time * 1000; time = new_countdown; localStorage.setItem('saved_countdown', new_countdown); } else { time = saved_countdown; } const x = setInterval(() => { var now = new Date().getTime(); var distance = time - now; var timeLeft = millisToMinutesAndSeconds(distance) if ($('#timeRemaining').length){ document.getElementById("timeRemaining").innerHTML = timeLeft; } if (distance/1000 <= 0) { clearInterval(x); localStorage.removeItem('saved_countdown'); $('#timeRemaining').css('color', 'red'); $('#timeRemaining').html("CONCLUSO"); // 清除DOM上的定时器ID记录 $('#timeRemaining').removeData('timerId'); location.href = URL + "teoria/saveExam"; } }, 1000); // 将定时器ID存储到DOM元素的自定义属性 $('#timeRemaining').data('timerId', x); }
内容的提问来源于stack exchange,提问作者m.Sarto
相关产品推荐
相关产品推荐

