javascript:清除所有超时?

时间:2012-01-14 04:39:07

标签: javascript timeout

有没有办法清除特定窗口的所有超时?我想超时存储在window对象的某处,但无法确认。

欢迎任何跨浏览器解决方案。

11 个答案:

答案 0 :(得分:110)

它们不在window对象中,但是它们有id,其中(afaik)是连续的整数。

所以你可以清除所有超时:

var id = window.setTimeout(function() {}, 0);

while (id--) {
    window.clearTimeout(id); // will do nothing if no timeout with id is present
}

答案 1 :(得分:69)

我认为实现此目标的最简单方法是将所有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]);
}

答案 2 :(得分:11)

我添加了Pumbaa80's answer,可能对开发旧IE的人有用。

是的,所有主流浏览器都将超时ID实现为连续整数(not required by specification)。通过起始编号从浏览器到浏览器不同。似乎Opera,Safari,Chrome和IE&gt; 8启动超时ID从1,基于Gecko的浏览器从2和IE&lt; = 8从一些随机数中神奇地保存在选项卡刷新中。你可以discover it yourself

在IE&lt; = 8 while (lastTimeoutId--)周期中,所有这些都可以运行超过8个数字并在此页面上显示&#34; A脚本导致Internet Explorer运行缓慢&#34;信息。因此,如果您不能save all you timeout id's或不想override window.setTimeout,您可以考虑在页面上保存第一个超时ID并清除超时时间。

在早期页面加载时执行代码:

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);
    };
});

然后清除所有可能由外国代码设置的挂起超时

答案 3 :(得分:7)

如何在全局数组中存储超时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
    }
};

答案 4 :(得分:1)

无需更改任何现有代码,就可以将以下代码之前放置在其他任何地方,它将为原始setTimeoutclearTimeout创建一个包装函数,并添加一个新的clearTimeouts,它将清除所有超时(Gist link

// 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 ){
    // also, wrap the callback, so the cache referece will be removed 
    // when the timerout has reached (fired the callback)
    var id = _set(function(){
        CB();
        removeCacheItem(id);
    }, duration || 0);

    cache.push( id ); // store reference in the cache array

    // id must be returned to the user could save it and clear it if they choose to
    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(){
    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);

答案 5 :(得分:1)

您必须重写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();
  }
}

答案 6 :(得分:1)

这很晚了……但是:

基本上,setTimeout / setInterval ID是连续的,所以只需创建一个虚拟超时函数来获取最高的ID,然后清除所有低于该ID的间隔。

const highestId = window.setTimeout(() => {
  for (let i = highestId; i >= 0; i--) {
    window.clearInterval(i);
  }
}, 0);

答案 7 :(得分:0)

使用全局超时,所有其他函数都从中获取时序。这将使一切运行得更快,并且更易于管理,尽管它会为您的代码添加一些抽象。

答案 8 :(得分:0)

我们刚刚发布了一个解决这个问题的软件包。

npm install time-events-manager

通过这种方式,您可以通过timeoutCollection&amp ;;查看所有超时和时间间隔。 intervalCollection个对象。 还有一个removeAll函数可以清除集合和浏览器中的所有超时/间隔。

答案 9 :(得分:0)

为完整起见,我想发布一个涵盖setTimeoutsetInterval的通用解决方案。

似乎浏览器可能对两者使用相同的ID池,但是从对Are clearTimeout and clearInterval the same?的一些回答来看,尚不清楚依靠clearTimeoutclearInterval执行是否安全相同的功能或仅适用于各自的计时器类型。

因此,当目标是消除所有超时和时间间隔时,以下实施方式在无法测试所有实施方式和实施方式时可能会更具防御性:

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(){}
}

您可以使用它清除当前窗口中的所有计时器:

clearAll(window);

或者您可以使用它清除iframe中的所有计时器:

clearAll(document.querySelector("iframe").contentWindow);

答案 10 :(得分:0)

我将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
        }
    }