2012-01-14 3 views
61

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

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

+0

Возможный дубликат [Как остановить все таймауты и интервалы с помощью javascript?] (Http://stackoverflow.com/questions/3141064/how-to-stop-all-timeouts-and-intervals-using-javascript) –

+0

Чувак, этот вопрос с 3 лет назад и имеет в нем отличные ответы. Не нужно возиться с этим. – marcio

+0

Я искал это и нашел оба.Ты был старше, поэтому я подумал, что это будет хорошая домашняя работа, чтобы свести два вопроса к одному. Шахта - всего один голос; еще несколько человек должны будут проголосовать за закрытие, а дублируемая ссылка может помочь другим. –

ответ

95

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

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

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

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

Является ли эта часть спецификации, или она может быть зависимой от реализации? –

+0

Это определенно зависит от реализации. Но все браузеры, которые, как мне известно, используют какой-то механизм инкремента. Может не начинаться с 1, хотя. – user123444555621

+4

Не нужно начинать с 1. Спецификация [HTML5] (http://www.w3.org/TR/html5/timers.html#timers) говорит: «Пусть дескриптор представляет собой целое число, определяемое пользователем, которое больше, чем ноль, который будет определять таймаут, который будет установлен этим вызовом ». который оставляет место для дескриптора как любое целое положительное число, включая не последовательные и не маленькие числа. –

58

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

У этого есть бонус (или потенциальный недостаток, я думаю), только очищающий те, которые * вы * установили, чтобы вы случайно не нарушили внешний код. –

+1

+1, не будет очищать все таймауты, но это хорошее решение для очистки определенной группы тайм-аутов сразу – marcio

+1

Это лучшее решение, потому что оно не нарушит внешний код, но поскольку я спросил, как очистить все таймауты, я закончил Принимая @ Pumbaa80 ответ :) – marcio

1

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

+0

Я вас не совсем понимаю. Вы хотите расширить поведение глобальной функции 'set_timeout'? Не могли бы вы привести пример кода? – marcio

+1

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

9

У меня есть дополнение к Pumbaa80's answer, которое может быть полезно для тех, кто разрабатывает старые IE.

Да, все основные браузеры используют идентификаторы тайм-аута как целые целые числа (это not required by specification). По прошествии стартового номера браузер отличается от браузера. Кажется, что Opera, Safari, Chrome и IE> 8 запускают идентификаторы тайм-аута из 1, основанных на Gecko браузеров от 2 и IE < = 8 от случайного числа, которое волшебным образом сохраняется при обновлении табуляции. Вы можете discover it yourself.

Все, что Меенс, что в IE < = 8, while (lastTimeoutId--) цикла может пробегать 8digits раз и показать «Скрипт на этой странице вызывает Internet Explorer, чтобы работать медленно» сообщения. Поэтому, если вы не можете save all you timeout id's или не хотите override window.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); 
    }; 
}); 

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

+0

плюс один для уточнения более подробной информации. –

5

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

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

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

npm install time-events-manager

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