Как очиститьInterval с неизвестным ID?
Скажите, что кто-то (зло) установил нам таймер с setInterval
, но мы не знаем его идентификатор (у нас нет ссылки на объект, который возвращает setInterval или его значение)
(function(){
setInterval(function(){console.log('pwned')},
10000)
})();
Есть ли способ, как его очистить? Можно ли использовать таймер другим способом? Или, по крайней мере, в частности браузер /javascript engine?
Дэвид Флэнаган затрагивает подобную тему своим большим JSTDG.
setInterval() method, use in malicious code
введите в индексные точки значение
... Некоторые браузеры обнаруживают повторяющиеся диалоговые окна и длинные сценарии и дают пользователю возможность их остановить. Но вредоносный код может использовать такие методы, как setInterval(), чтобы загружать CPU и также атаковать вашу систему, выделяя много памяти. Там есть нет общего способа, которым веб-браузеры могут предотвратить такую хамскую атаку. В практика, это не является общей проблемой в Сети, так как никто не возвращается на сайт, который участвует в этом злоупотреблении скриптами!
Ответы
Ответ 1
Из быстрого теста все основные браузеры (последние версии 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);
}
#Placeholder div { width: 80px; float: left; }
<button type="button" onclick="ClearAllIntervals();">Clear All</button>
<div id="Placeholder">
<div id="Tick"></div>
<div id="Tack"></div>
</div>
Ответ 2
Ну, эмпирически испытания в Chrome показывают, что setInterval
возвращает число, которое увеличивается для каждого вызова. Поэтому, если вы уверены, что setInterval был последним, установите следующее:
function clearLastInterval () {
var i = setInterval (function () {}, 10000);
clearInterval (i-1);
clearInterval (i);
}
Я не уверен, что рекомендую это, хотя: -)
Ответ 3
Я попробовал подход, предложенный #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
Я решил это, используя localstorage, сохранив там идентификатор setInterval и подберев его позже, чтобы очистить этот интервал..