Чи є спосіб очистити весь час виходу з даного вікна? Я припускаю, що тайм-аути зберігаються десь в window
об'єкті, але не могли підтвердити це.
Будь-яке крос-браузерне рішення вітається.
Чи є спосіб очистити весь час виходу з даного вікна? Я припускаю, що тайм-аути зберігаються десь в 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, яке може бути корисним для тих, хто розробляє старі IE.
Так, всі основні браузери реалізують ідентифікатори таймауту як послідовні цілі числа (що не вимагається специфікацією ). Через стартовий номер відрізняється форма браузера від браузера. Здається, що Opera, Safari, Chrome та IE> 8 запускає ідентифікатор тайм-ауту з 1, браузери на базі Gecko з 2 та IE <= 8 з якогось випадкового числа, яке магічно зберігається через оновлення вкладки. Ви можете відкрити це самостійно .
Все, що означає, що в IE <= 8 while (lastTimeoutId--)
цикл може працювати протягом 8-тициткових разів і показувати повідомлення " Сценарій на цій сторінці змушує Internet Explorer повільно працювати ". Таким чином, якщо ви не можете зберегти всі ваші ідентифікатори таймауту або не хочете переосмислити 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);
};
});
А потім зніміть всі очікувані очікування, які, ймовірно, були встановлені іноземним кодом стільки разів, скільки вам потрібно
Як щодо зберігання ідентифікаторів тайм-ауту в глобальному масиві та визначення способу делегування виклику функції вікні.
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
}
};
Ви повинні переписати window.setTimeout
метод і зберегти його ідентифікатор таймауту.
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();
}
}
Розмістіть наведений нижче код перед будь-яким іншим сценарієм, і він створить функцію обгортки для оригіналу setTimeout
& clearTimeout
.
clearTimeouts
До window
Об’єкту будуть додані нові методи , які дозволять очистити всі (очікувані) тайм-аути ( посилання Gist ).
Інші відповіді не мають повної підтримки для можливих аргументів
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);
Для повноти я хотів опублікувати загальне рішення, яке охоплює і те, setTimeout
і setInterval
.
Здається, браузери можуть використовувати однаковий пул ідентифікаторів для обох, але з деяких відповідей на те, чи ClearTimeout та clearInterval однакові? , незрозуміло, чи безпечно покладатися на clearTimeout
та clearInterval
виконувати ту саму функцію чи працювати лише над відповідними типами таймерів.
Тому, коли мета знищити всі тайм-аути та інтервали, ось реалізація, яка може бути дещо захиснішою у всіх реалізаціях, коли неможливо протестувати їх усі:
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);
Я використовую 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
}
}
Використовуйте глобальний тайм-аут, з якого виходять усі ваші інші функції. Це зробить все швидше і легше керувати, хоча це додасть деякої абстракції у ваш код.
set_timeout
глобальної функції? Чи можете ви навести приклад коду?
Ми щойно опублікували пакет, що вирішує цю проблему.
npm install time-events-manager
З цим ви можете переглядати всі тайм-аути та інтервали через timeoutCollection
& intervalCollection
об’єкти. Існує також removeAll
функція, яка очищає всі тайм-аути / інтервали як з колекції, так і з браузера.
Це дуже пізно ... але:
В основному, ідентифікатор setTimeout / setInterval йде в послідовному порядку, тому просто створіть фіктивну функцію тайм-ауту, щоб отримати найвищий ідентифікатор, а потім очистіть інтервал для всіх ідентифікаторів, нижчих за цей.
const highestId = window.setTimeout(() => {
for (let i = highestId; i >= 0; i--) {
window.clearInterval(i);
}
}, 0);