javascript:清除所有超时?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8860188/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javascript: Clear all timeouts?
提问by marcio
Is there a way to clear all time outs from a given window? I suppose the timeouts are stored somewhere in the window
object but couldn't confirm that.
有没有办法清除给定窗口中的所有超时?我想超时存储在window
对象的某个地方,但无法确认。
Any cross browser solution is welcome.
欢迎任何跨浏览器解决方案。
回答by user123444555621
They are not in the window object, but they have ids, which (afaik) are consecutive integers.
它们不在 window 对象中,但是它们有 id,它们(afaik)是连续的整数。
So you may clear all timeouts like so:
所以你可以像这样清除所有超时:
var id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id); // will do nothing if no timeout with id is present
}
回答by Michael Berkowski
I think the easiest way to accomplish this would be to store all the setTimeout
identifiers in one array, where you can easily iterate to clearTimeout()
on all of them.
我认为实现这一点的最简单方法是将所有setTimeout
标识符存储在一个数组中,您可以在其中轻松迭代所有标识符clearTimeout()
。
var timeouts = [];
timeouts.push(setTimeout(function(){alert(1);}, 200));
timeouts.push(setTimeout(function(){alert(2);}, 300));
timeouts.push(setTimeout(function(){alert(3);}, 400));
for (var i=0; i<timeouts.length; i++) {
clearTimeout(timeouts[i]);
}
回答by Kolya Ay
I have an addition to Pumbaa80's answerthat might be useful for someone developing for old IEs.
我对Pumbaa80 的回答有一个补充,可能对为旧 IE 开发的人有用。
Yes, all major browsers implement timeout ids as consecutive integers (which is not required by specification). Althrough the starting number differs form browser to browser. It seems that Opera, Safari, Chrome and IE > 8 starts timeout ids from 1, Gecko-based browsers from 2 and IE <= 8 from some random number that is magically saved across tab refresh. You can discover it yourself.
是的,所有主要浏览器都将超时 ID 实现为连续整数(规范不需要)。整个浏览器的起始编号不同。似乎 Opera、Safari、Chrome 和 IE > 8 从 1 开始超时 ID,基于 Gecko 的浏览器从 2 和 IE <= 8 从某个随机数开始,这些随机数在选项卡刷新时神奇地保存。你可以自己去发现。
All that meens that in IE <=8 the while (lastTimeoutId--)
cycle may run over 8digits times and show the "A script on this page is causing Internet Explorer to run slowly" message. So if you can not save all you timeout id'sor don't want to override window.setTimeoutyou may consider saving the first timeout id on a page and clearing timeouts until it.
所有这一切都意味着在 IE <=8 中,while (lastTimeoutId--)
循环可能会运行超过8 位数字并显示“此页面上的脚本导致 Internet Explorer 运行缓慢”消息。因此,如果您无法保存所有超时 ID或不想覆盖 window.setTimeout,您可以考虑在页面上保存第一个超时 ID 并清除超时直到它。
Execute the code on early page load:
在早期页面加载时执行代码:
var clearAllTimeouts = (function () {
var noop = function () {},
firstId = window.setTimeout(noop, 0);
return function () {
var lastId = window.setTimeout(noop, 0);
console.log('Removing', lastId - firstId, 'timeout handlers');
while (firstId != lastId)
window.clearTimeout(++firstId);
};
});
And then clear all pending timeouts that probably was set by foreign code so many times you want
然后清除所有可能由外部代码设置的所有挂起超时您想要的次数
回答by Jaskey
How about store the timeout ids in a global array, and define a method to delegate the function call to the window's.
如何将超时 id 存储在全局数组中,并定义一个方法将函数调用委托给窗口。
GLOBAL={
timeouts : [],//global timeout id arrays
setTimeout : function(code,number){
this.timeouts.push(setTimeout(code,number));
},
clearAllTimeout :function(){
for (var i=0; i<this.timeouts.length; i++) {
window.clearTimeout(this.timeouts[i]); // clear all the timeouts
}
this.timeouts= [];//empty the id array
}
};
回答by vsync
To clear all timeoutsthey must be "captured" first:
要清除所有超时他们必须“捕获”第一:
Place the below code before any other scriptand it will create a wrapper function for the original setTimeout
& clearTimeout
.
将以下代码放在任何其他脚本之前,它将为原始setTimeout
&创建一个包装函数clearTimeout
。
A new clearTimeouts
methods will be added to the window
Object, which will allow clearing all(pending) timeouts (Gist link).
一个新clearTimeouts
方法将被添加到window
对象中,这将允许清除所有(待处理)超时(要点链接)。
Other answers lack completesupport for possible arguments
setTimeout
might receive.
其他答案缺乏对可能收到的可能论点的完全支持。
setTimeout
// isolated layer wrapper (for the local variables)
(function(_W){
var cache = [], // will store all timeouts IDs
_set = _W.setTimeout, // save original reference
_clear = _W.clearTimeout // save original reference
// Wrap original setTimeout with a function
_W.setTimeout = function( CB, duration, arg ){
// also, wrap the callback, so the cache reference will be removed
// when the timeout has reached (fired the callback)
var id = _set(function(){
CB.apply(null, arguments)
removeCacheItem(id)
}, duration || 0, arg)
cache.push( id ) // store reference in the cache array
// id reference must be returned to be able to clear it
return id
}
// Wrap original clearTimeout with a function
_W.clearTimeout = function( id ){
_clear(id)
removeCacheItem(id)
}
// Add a custom function named "clearTimeouts" to the "window" object
_W.clearTimeouts = function(){
console.log("Clearing " + cache.length + " timeouts")
cache.forEach(n => _clear(n))
cache.length = []
}
// removes a specific id from the cache array
function removeCacheItem( id ){
var idx = cache.indexOf(id)
if( idx > -1 )
cache = cache.filter(n => n != id )
}
})(window);
回答by guest
You have to rewrite the window.setTimeout
method and save its timeout ID.
您必须重写该window.setTimeout
方法并保存其超时 ID。
const timeouts = [];
const originalTimeoutFn = window.setTimeout;
window.setTimeout = function(fun, delay) { //this is over-writing the original method
const t = originalTimeoutFn(fn, delay);
timeouts.push(t);
}
function clearTimeouts(){
while(timeouts.length){
clearTimeout(timeouts.pop();
}
}
回答by Chris Calo
For completeness, I wanted to post a general solution that covers both setTimeout
and setInterval
.
为了完整起见,我想发布一个涵盖setTimeout
和的通用解决方案setInterval
。
It seems browsers might use the same pool of IDs for both, but from some of the answers to Are clearTimeout and clearInterval the same?, it's not clear whether it's safe to rely on clearTimeout
and clearInterval
performing the same function or only working on their respective timer types.
似乎浏览器可能对两者使用相同的 ID 池,但从一些答案来看,Are clearTimeout 和 clearInterval 是否相同?,目前尚不清楚依赖clearTimeout
并clearInterval
执行相同功能或仅使用各自的计时器类型是否安全。
Therefore, when the goal is to kill all timeouts and intervals, here's an implementation that might be slightly more defensive across implementations when unable to test all of them:
因此,当目标是终止所有超时和间隔时,下面的实现在无法测试所有实现时可能会稍微更具防御性:
function clearAll(windowObject) {
var id = Math.max(
windowObject.setInterval(noop, 1000),
windowObject.setTimeout(noop, 1000)
);
while (id--) {
windowObject.clearTimeout(id);
windowObject.clearInterval(id);
}
function noop(){}
}
You can use it to clear all timers in the current window:
您可以使用它来清除当前窗口中的所有计时器:
clearAll(window);
Or you can use it to clear all timers in an iframe
:
或者您可以使用它来清除 中的所有计时器iframe
:
clearAll(document.querySelector("iframe").contentWindow);
回答by user3010152
I use Vue with Typescript.
我将 Vue 与 Typescript 一起使用。
private setTimeoutN;
private setTimeoutS = [];
public myTimeoutStart() {
this.myTimeoutStop();//stop All my timeouts
this.setTimeoutN = window.setTimeout( () => {
console.log('setTimeout');
}, 2000);
this.setTimeoutS.push(this.setTimeoutN)//add THIS timeout ID in array
}
public myTimeoutStop() {
if( this.setTimeoutS.length > 0 ) {
for (let id in this.setTimeoutS) {
console.log(this.setTimeoutS[id]);
clearTimeout(this.setTimeoutS[id]);
}
this.setTimeoutS = [];//clear IDs array
}
}
回答by Bar Goldinfeld
We've just published a package solving this exact issue.
我们刚刚发布了一个包来解决这个确切的问题。
npm install time-events-manager
npm install time-events-manager
With that, you can view all timeouts and intervals via timeoutCollection
& intervalCollection
objects.
There's also a removeAll
function which clears all timeouts/intervals both from the collection and the browser.
有了它,您可以通过timeoutCollection
&intervalCollection
对象查看所有超时和间隔。还有一个removeAll
功能可以清除集合和浏览器中的所有超时/间隔。
回答by Travis J
Use a global timeout which all of your other functions derive timing from. This will make everything run faster, and be easier to manage, although it will add some abstraction to your code.
使用全局超时,您的所有其他函数都从中获得计时。这将使一切运行得更快,更易于管理,尽管它会为您的代码添加一些抽象。