Как очистить интервал с неизвестным идентификатором?
Автор вопроса: mykhalОтветов: 4
Скажем, кто-то (зло) установил нам таймер с setInterval, но мы не знаем его ID (у нас нет ни ссылки на объект, который возвращает setInterval, ни его значения)
Есть ли способ, как его очистить? Можно ли получить доступ к таймеру каким-то другим способом? Или, по крайней мере, в конкретном браузере/движке javascript?
Дэвид Флэнаган затрагивает аналогичную тему в своем большом JSTDG. Ключ setInterval() method, use in malicious code в указателе указывает на
... Некоторые браузеры обнаруживают повторяющиеся диалоговые окна и длительные сценарии и дают пользователю возможность остановить их. Но вредоносный код может использовать такие методы, как setInterval(), для загрузки ЦП, а также может атаковать вашу систему, выделяя много памяти. Не существует общего способа, с помощью которого веб-браузеры могли бы предотвратить такого рода неуклюжие атаки. На практике это не является распространенной проблемой в Интернете, поскольку никто не возвращается на сайт, который занимается подобным злоупотреблением сценариями!
Связано - stackoverflow.com/questions/3141064/ Shadow Wizard Wearing Mask V2 27.07.2011
Хм.. еще одна идея - случайно они не дают функции имя? Shadow Wizard Wearing Mask V2 27.07.2011
Shadow Wizard, в данном случае, к сожалению, был установлен в закрытии (что иногда считается хорошей функцией для использования в целях безопасности).. я знаю, этот вопрос несколько теоретический, потому что мы, вероятно, можем в большинстве случаев найти и отредактировать неприятный код локально в некоторых браузерах mykhal 27.07.2011
Shadow Wizard... эээ, может быть, это не совсем закрытие. но это анонимная функция, которая была выполнена. наличие ссылки на функцию поможет нам как-то? mykhal 27.07.2011
да, вы можете (по крайней мере теоретически) переопределить функцию и поместить свою собственную функцию со своим собственным кодом. Функция, объявленная последней с тем же именем, будет выполняться во время выполнения. Shadow Wizard Wearing Mask V2 27.07.2011
Из быстрого теста все основные браузеры (последние версии Chrome, Firefox и IE) дают довольно маленькие числа в качестве идентификатора, поэтому просто "слепой" цикл по всем возможным числам должен работать нормально:
function ClearAllIntervals() {
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
}
Полный пример:
window.onload = function() {
window.setInterval(function() {
document.getElementById("Tick").innerHTML += "tick<br />";
}, 1000);
window.setInterval(function() {
document.getElementById("Tack").innerHTML += "tack<br />";
}, 1000);
};
function ClearAllIntervals() {
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
}
Это остановит все интервалы, не может остановить определенный интервал, не зная его ID, конечно.
Как вы можете проверить сами, он должен работать во всех основных браузерах, упомянутых выше.
Ответ 2 · рейтинг 13 · HBP
Что ж, эмпирические испытания в Chrome показывают, что setInterval возвращает число, которое увеличивается при каждом вызове. Поэтому, если вы УВЕРЕНЫ, что setInterval был последним установленным, будет работать следующее:
function clearLastInterval () {
var i = setInterval (function () {}, 10000);
clearInterval (i-1);
clearInterval (i);
}
Я не уверен, что буду рекомендовать это, хотя ;-)
Ответ 3 · рейтинг 8 · Mark Chackerian
Я попробовал подход, предложенный #Shadow Wizard, и он сработал при очистке интервала. Однако впоследствии этот подход имел побочные эффекты. В моем конкретном случае я не смог использовать jquery.fadeTo() после очистки всех интервалов.
Подход, на котором я остановился, является более чистым решением, которое заключается в переопределении метода setInterval и сохранении идентификаторов интервалов в переопределенных методах. Как показано здесь, я помещаю идентификаторы в массив, а затем очищаю их все. Немного уточнив структуру хранения массивов, вы можете пометить их и выборочно очистить.
var intervalTracking = new Array();
var intervalCount=0;
window.oldSetInterval = window.setInterval;
window.setInterval = ( function(func, interval) {
var interval = oldSetInterval(func, interval);
intervalTracking[++intervalCount]=interval;
return interval;
});
function clearAllIntervals() {
for (var i = 0 ; i <= intervalCount ; i++) {
window.clearInterval( intervalTracking[i] );
}
}
Кажется, это работает!
Ответ 4 · Daniel Garcia Sanchez
Я решил это, используя localstorage, сохранив там идентификатор setInterval и забрав его позже, чтобы очистить этот интервал.