有没有一种方法可以同时清除所有的JavaScript定时器?

27
我正在使用jQuery.load为我的网站构建自动刷新评论区,因此我正在使用JavaScript的'setTimeout'计时器来检查新评论。
但是在进行一些操作(例如使用ajax更改评论页面或删除评论)后,有一些旧计时器仍在运行,尽管我在加载新的ajax内容之前使用了clearTimeout。
当我加载新的ajax内容时,有没有清除所有JavaScript计时器的方法?
4个回答

44

警告:以下代码存在问题,主要是因为该需求本身就存在问题。我想知道为什么您会想要清除所有计时器。这将使您的代码破坏使用计时器的插件,而这比您想象的要常见得多,除非您正在调试或玩乐,否则这并不重要。


如果您一定要这样做:

这是最糟糕的解决方案之一。但是,它揭示了JavaScript本身的一个潜在安全漏洞。但是由于它确实起作用(清除了所有计时器),所以我想分享一下:

var maxId = setTimeout(function(){}, 0);

for(var i=0; i < maxId; i+=1) { 
    clearTimeout(i);
}

4
尽管被接受的答案是一个很酷的最佳实践,但这个回答解答了标题中提出的问题。 - Joe Coder
这是一个很好的解决方案!我猜它可以跨浏览器使用,对吗? - 0xC0DEGURU
1
基于我的经验,我可以说是的。但你应该试一试。不管怎样,这样做非常糟糕!你为什么要这样做! - Omar Al-Ithawi
1
我认为标准中没有规定计时器ID必须像那样递增,因此某些浏览器可能会更改它并导致代码出错。然而,随机生成ID并跟踪它们比仅递增计数器要更费力。 - Tim Tisdall
那对我来说真的非常有用。当某些东西失控时,它可以在调试时提供帮助,但您不想重置整个页面。 - Jamie Brown
显示剩余8条评论

31

在 JavaScript 中,没有通用函数可以清除所有计时器。您需要跟踪所有创建的计时器。为此,您可以使用全局数组:

var timers = [];
...
// add a timer to the array
timers.push(setTimeout(someFunc, 1000));
...
// clear all timers in the array
for (var i = 0; i < timers.length; i++)
{
    clearTimeout(timers[i]);
}

1
问题在于我的新加载的ajax内容无法控制旧的运行计时器。 - Jens
1
这就是为什么我建议使用全局变量。 - Darin Dimitrov
我一直在苦苦挣扎,太棒了!谢谢。 - Doug Wolfgram
while (id = timers.pop()) clearTimeout(id); <- 我更喜欢这个,但实际上并没有太大区别,for循环同样好用 - 尽管我不能在id声明前加上varlet,这很糟糕 - 你可以使用 for(let id=timers.pop();id;id=timers.pop()) clearTimeout(id),但这样就失去了更好的外观。 - James Stevens

2

您可能想考虑使用jQuery计时器,它抽象了许多setTimeout / setInterval的“丑陋”细节,并使它们更容易用于您描述的类似功能的代码中。


@Benubird - 不幸的是,这是我能找到的最新版本。如果你有更新的版本,请告诉我... - Justin Ethier
是的,看起来没有当前版本(https://dev59.com/LFDTa4cB1Zd3GeqPIVvb),可能不再可用。 - Benubird

1
这可能会有所帮助。我有一个用户创建计时器的情况,类似于开放式开发平台,显然我无法访问这些计时器的ID。因此,我需要对它们进行沙盒处理,并在必要时将它们全部删除。为此,我创建了一个隐藏的<iframe>并在其中加载所有计时器。要删除所有计时器,只需删除该iframe即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接