Как очистить Интервал с неизвестным идентификатором? - PullRequest
20 голосов
/ 27 июля 2011

Скажем, кто-то (зло) установил нам таймер с setInterval, но мы не знаем его ID (у нас нет ссылки на объект, который возвращает setInterval, ни его значения)

(function(){
  setInterval(function(){console.log('pwned')},
              10000)
})();

Есть ли способ, как это очистить?Можно ли получить доступ к таймеру другим способом?Или, по крайней мере, в частности браузер / движок JavaScript?

Дэвид Фланаган затрагивает аналогичную тему своей большой JSTDG.setInterval() method, use in malicious code введите в индекс указатель на

... Некоторые браузеры обнаруживают повторяющиеся диалоговые окна и долго выполняющиеся сценарии и дают пользователю возможность их остановить.Но вредоносный код может использовать такие методы, как setInterval (), для загрузки ЦП, а также может атаковать вашу систему, выделяя много памяти.Нет общего способа, которым веб-браузеры могли бы предотвратить подобные атаки.На практике это не является распространенной проблемой в Интернете, поскольку никто не возвращается на сайт, который занимается подобным злоупотреблением сценариями!

Ответы [ 4 ]

40 голосов
/ 27 июля 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);
}
#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>

Это остановит все интервалы, не может остановить определенный интервал, не зная его ID курса.

Как вы можете проверить самостоятельно, он должен работать во всех основных браузерах, упомянутых выше.

13 голосов
/ 27 июля 2011

Что ж, эмпирические испытания в Chrome показывают, что setInterval возвращает число, которое увеличивается для каждого вызова.Так что, если вы уверены, что setInterval был последним установленным, будет работать следующее:

function clearLastInterval () {
  var i = setInterval (function () {}, 10000);
  clearInterval (i-1);
  clearInterval (i);
}

Я не уверен, что рекомендую это, хотя; -)

6 голосов
/ 05 октября 2011

Я попробовал подход, предложенный #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] );
    }
}

Это похоже на работу!

0 голосов
/ 11 сентября 2015

Я решил это, используя localstorage, сохранив там идентификатор setInterval и подняв его позже, чтобы очистить этот интервал.

...