使用定时器实现停止页面所有js的原理

最近有一个轮播图调试,但是页面的轮播图一直在动,鼠标选不中css样式,最后在网上找了这么一段代码,

var id = setInterval(function() {}, 0);
while (id--) clearInterval(id);

可以停止页面所有js,
但不知道这是为什么,曾经用

for(;;){}

替代过,但浏览器会卡死,一直搞不清这个是什么原理
但这个就没事

会用,但不知道为什么会有这样的效果,
所有想看看有没有大神能分析一下

阅读 7.7k
5 个回答
var id = setInterval(function() {}, 0);

创建了一个新的定时器并立刻执行,setInterval返回值为一个整数,是这个定时器的唯一ID,利用了
setInterval 和 setTimeout 的返回值一定是递增的整数这一特性,所以获得到的ID的值一定大于之前设置的所有定时器的值。

 while (id--) clearInterval(id);

逐个语句来看

while(id--){//1
    clearInterval(id);//2
}

1: 将ID减一并返回给while,这里利用了while的判断条件,如果条件是一个大于0的树,则认为是true,当条件为0,则认为是false,所以此处不会死循环,因为当id为0时,会跳出循环,而 for(;;){} 不会。
2: clearInterval(id),将现在的ID所对应的那个定时器清除,clearInterval 语句也可以清除 setTimeout 设置的定时器,clearInterval和clearTimeout是等效的(来源一),而且因为前文提到的 setInterval 和 setTimeout 的返回值一定是递增的整数, 所以通过这个循环可以遍历所有一定被设定好的定时器并全部清除。
PS:虽然是递增的但不一定是连续的整数,clearInterval的入参如果不对应这么一个定时器也不会报错(来源二)。
参考:
来源一:which means you can technically use clearTimeout() and clearInterval() interchangeably——出自MDN-WindowTimers.clearTimeout()
来源二:Passing an invalid ID to clearTimeout() silently does nothing; no exception is thrown.——出自MDN-WindowTimers.clearTimeout()

这段代码先创建一个定时器并获取这个定时器的ID,然后递减这个ID并结束ID对应的定时器,实际上是利用了定时器的ID会从小到大递增分配的特点,实际上并不是每次迭代都有对应的定时器存在

至于你那个for循环不是死循环么...

这段代码是关闭所有的setInterval
每次setInterval的时候都会返回一个自增数字,可以理解为定时器的id

var id = setInterval(function() {}, 0);//创建一个定时器拿到最后一个定时器的id
while (id--) clearInterval(id);//拿到最后一个id然后递减 就关闭所有的了

既然是轮播图,原生的话肯定有定时器在执行,找到那个定时clear掉轮播图不就不动了

如果是用的轮播图插件,肯定会提供不自动轮播的选项,或者提供手动停止的api。

靠阻塞不太靠谱

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题