javascript: очистить все таймауты?


есть ли способ очистить все тайм-ауты из данного окна? Я предполагаю, что тайм-ауты хранятся где-то в window объект, но не может подтвердить это.

любое кросс-браузерное решение приветствуется.

7 70

7 ответов:

они не находятся в объекте window, но у них есть идентификаторы, которые (afaik) являются последовательными целыми числами.

таким образом, вы можете очистить все таймауты следующим образом:

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

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

Я думаю, что самый простой способ сделать это было бы хранить все 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]);
}

у меня есть дополнение к Pumbaa80 это это может быть полезно для кого-то, кто развивается для старых IEs.

Да, все основные браузеры реализуют идентификаторы таймаута как последовательные целые числа (что не требуется по спецификации). Хотя начальное число отличается от браузера к браузеру. Кажется, что Opera, Safari, Chrome и IE > 8 запускает идентификаторы таймаута из 1, браузеры на основе Gecko из 2 и IE откройте его сами.

все это означает, что в IE while (lastTimeoutId--) цикл может работать более 8digits раз и показать "скрипт на этой странице заставляет Internet Explorer работать медленно" сообщение. Так что если вы не можете сохранить все, что вы тайм-аут удостоверение или не хотят окне переопределения.setTimeout вы можете сохранить первый идентификатор таймаута на странице и очистить таймауты до тех пор, пока оно.

выполнить код при ранней загрузке страницы:

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

а затем очистите все ожидающие таймауты, которые, вероятно, были установлены иностранным кодом так много раз, что вы хотите

Как насчет хранения идентификаторов таймаута в глобальном массиве и определения метода для делегирования вызова функции окну.

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

используйте глобальный тайм-аут, из которого все ваши другие функции получают время. Это будет все работать быстрее, и легче управлять, хотя это добавит некий абстрактный код.

мы только что опубликовали пакет, решающий эту точную проблему.

npm install time-events-manager

С этим, вы можете просмотреть все таймауты и интервалы через timeoutCollection & intervalCollection объекты. Там также есть removeAll функция, которая очищает все таймауты / интервалы как из коллекции, так и из браузера.

без изменения любого существующего кода, Вы можете разместить ниже код до что-нибудь еще, и он будет создавать функции обертки для оригинала setTimeout & clearTimeout, а также добавить новый clearTimeouts что будет понятно все тайм-ауты

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