如何使用未知ID清除Interval?

myk*_*hal 22 javascript timer setinterval clearinterval

假设有人(邪恶)为我们设置了一个计时器setInterval,但是我们不知道它的ID(我们没有对该对象的引用,setInterval正在返回,也没有它的值)

(function(){
  setInterval(function(){console.log('pwned')},
              10000)
})();
Run Code Online (Sandbox Code Playgroud)

有办法,如何清除它?是否有可能以其他方式访问计时器?或者至少特别是浏览器/ javascript引擎?

大卫·弗拉纳根(David Flanagan)接触了他的大型JSTDG. setInterval() method, use in malicious code索引中的键指向

...某些浏览器会检测重复的对话框和长时间运行的脚本,并为用户提供停止它们的选项.但是恶意代码可以使用setInterval()等方法来加载CPU,也可以通过分配大量内存来攻击你的系统.Web浏览器没有一般的方法可以阻止这种火腿攻击.在实践中,这不是Web上的常见问题,因为没有人返回到从事此类脚本滥用的网站!

Sha*_*ard 43

从快速测试开始,所有主流浏览器(最新的Chrome,Firefox和IE)都提供相当小的数字作为ID,因此只需"盲目地"循环所有可能的数字应该可以正常工作:

function ClearAllIntervals() {
    for (var i = 1; i < 99999; i++)
        window.clearInterval(i);
}
Run Code Online (Sandbox Code Playgroud)

完整示例:

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);
}
Run Code Online (Sandbox Code Playgroud)
#Placeholder div { width: 80px; float: left; }
Run Code Online (Sandbox Code Playgroud)
<button type="button" onclick="ClearAllIntervals();">Clear All</button>
<div id="Placeholder">
    <div id="Tick"></div>
    <div id="Tack"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

这将停止所有间隔,当然不能在不知道其ID的情况下停止特定间隔.

由于您可以自己测试,它应该适用于上面提到的所有主要浏览器.

  • 蛮力,好的答案因为我认为OP会得到! (4认同)
  • 有点晚了 - 应该注意的是 `setInterval` 和 `setTimeout` 使用相同的 ID 池,所以这也会取消任何 `setTimeout`。 (2认同)

HBP*_*HBP 13

好吧,Chrome中的经验测试显示setInterval返回一个数字,每个调用都会递增.因此,如果您确定setInterval是最后一个set,则以下内容将起作用:

function clearLastInterval () {
  var i = setInterval (function () {}, 10000);
  clearInterval (i-1);
  clearInterval (i);
}
Run Code Online (Sandbox Code Playgroud)

我不确定我会推荐这个;-)


Mar*_*ian 8

我尝试了#Shadow向导建议的方法,它可以清除间隔.然而,这种方法之后会产生副作用.在我的特定情况下,我在清除所有间隔后无法使用jquery.fadeTo().

我确定的方法是一个更清晰的解决方案,即重新定义setInterval方法并在重新定义的方法中保存区间ID.如图所示,我将id放入一个数组中,然后清除所有这些数组.通过稍微改进一下存储阵列的结构,您可以标记它们并有选择地清除它们.

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] );
    }
}
Run Code Online (Sandbox Code Playgroud)

这似乎工作!