关于定时器setInterval()累加或者是重叠的问题
当给一个click事件添加定时器的时候,如果多次点击,而没有及时清除定时器,就会产生定时器累加的问题,具体表现为:调用函数的时间间隔越来越短,越来越快。
在使用setInterval()时会返回一个定时器的id值。利用这个id值,使用clearInterval(id),就可以将id是这个值的定时器关闭掉。
<button id="btn1">开始</button>
<button id="btn2">停止</button><script type="text/javascript">
var int;
btn1=document.getElementById("btn1");
btn2=document.getElementById("btn2");
btn1.onclick=function(){int=setInterval('console.log(2)',400);
}
btn2.onclick=function(){clearInterval(int);
}
</script>
一旦点击开始,就会开始定时器,调用函数,然后点击关闭,就可以把这个定时器关闭掉。
但是如果多次点击这个开始按钮,打印2的速度就会越来越快,此时点击停止按钮,好像不起作用?但是实际上,是起了作用的,此时点击它,只是关闭了最新打开的那个定时器,而无法关闭在这之前多次打开的定时器。
也就是说,这样写,停止按钮仅仅是关闭最新打开的那个定时器,就算连续点击停止按钮也没有,因为:
clearInterval(int);
里面的int是全局变量,在每次点击开始按钮生成新的定时器时,都会被最新的定时器id赋值。于是里面存储的值就一直是最新的定时器id,所以多次点击关闭不能关闭全部定时器。
将代码改成:
<button id="btn1">开始</button>
<button id="btn2">停止</button>
<button id="btn3">打印最新一个定时器的id</button>
<script type="text/javascript">
var int;
btn1=document.getElementById("btn1");
btn2=document.getElementById("btn2");
btn3=document.getElementById("btn3");
btn1.onclick=function(){int=setInterval('console.log(2)',400);
}
btn2.onclick=function(){clearInterval(int);
}
btn3.onclick=function(){alert(int);
}
</script>
尝试运行,当我只点击一下开始,就打印int中存储的定时器id,显示为2:
当我刷新后,点击两下开始按钮,再打印打印int中存储的定时器id,显示为3:
当我再次刷新后,点击三下开始按钮,再打印打印int中存储的定时器id,显示为4:
同样的,当我点击4次开始,id变成5;5次开始,id变成6……以此类推,也就是说,生成定时器时,其内存储的id值是整型数字,且按定时器生成的时间顺序,从2开始,一直到n。
如之前代码写的,int中存储的是最新的定时器id值,因为每生成一个新的定时器,int变量中存储的值就会被覆盖一次。
这样一来,就解释了为什么点击了多次开始按钮后,再点击关闭,就只能关闭最新生成的定时器的问题了。
有了这个猜想,我们还需要修改代码验证一下:
<button id="btn1">开始</button>
<button id="btn2">停止</button>
<!-- <button id="btn3">打印最新一个定时器的id</button> -->
<script type="text/javascript">
// var int;
btn1=document.getElementById("btn1");
btn2=document.getElementById("btn2");
// btn3=document.getElementById("btn3");
btn1.onclick=function(){int=setInterval('console.log(2)',400);
}
btn2.onclick=function(){clearInterval(2);clearInterval(3);clearInterval(4);clearInterval(5);
}
// btn3.οnclick=function(){// alert(int);
// }
</script>
既然定时器的id是数字,那么我们直接利用clearInterval()里面参数直接放数字,这里放2345,也就是说按之前的想法,我点击开始按钮4次,然后点击关闭,就会把这4个生成的定时器都关掉,不再打印:
结果确实是这样,也就是说之前的想法是正确的。
于是就可以利用这个强制关闭,太多的,自己也不知道id值的定时器了:
for(var i=0;i<100;i++){clearInterval(i);
}
这种方式就可以一次性无差别关闭100个定时器。
但是接下来,我又发现了一个问题,当我按了四次开始,又按了关闭按钮之后,id值为2345的定时器已经被关闭了。但是我又点击了4次开始按钮之后,却发现关闭按钮失效了!!
这肯定和int中存储的id值有关系,为了验证想法,将代码修改为:
<button id="btn1">开始</button>
<button id="btn2">停止</button>
<button id="btn3">打印最新一个定时器的id</button>
<script type="text/javascript">
var int;
btn1=document.getElementById("btn1");
btn2=document.getElementById("btn2");
btn3=document.getElementById("btn3");
btn1.onclick=function(){int=setInterval('console.log(2)',400);console.log(int);
}
btn2.onclick=function(){clearInterval(2);clearInterval(3);clearInterval(4);clearInterval(5);
}
btn3.onclick=function(){alert(int);
}
for(var i=0;i<100;i++){clearInterval(i);
}
</script>
我先点击了四次开始,然后关闭四个定时器(图中1部分),然后再点击开始,发现定时器的id并没有从头开始排布,而是变成6,继续走下去了!!
所以先前:
for(var i=0;i<100;i++){clearInterval(i);
}
其实关闭的仅仅是最开始定义的100个定时器。
结论:
1.每次创建一个定时器,就会返回一个属于这个定时器的唯一一个id值,且为整型数字,从2开始。
2.利用clearInterval(i);可以删除定时器,i对应要删除的定时器的id值,要删除哪个,就得找到它的id值。
3.删除定时器之后,再创建新的定时器,id并不会从头开始,而是顺延下去。
基于以上的三点认识,就可以知道解决定时器叠加的问题了:
我们定时器累加,无非是因为创建的旧定时器没有及时关闭,然后又创建了新的定时器,所以产生了累加效果。
反过来想,只要及时删除就可以,于是我们就可以在创建定时器的函数中加个判断,如果已经存在定时器,则先关闭旧定时器,再打开新定时器,这样一来,就能够保证只有最新的一个定时器在运行,而int中始终存储的恰好是最新的定时器id,这就可以避免叠加了!
<button id="btn1">开始</button>
<button id="btn2">停止</button>
<script type="text/javascript">
var int=null;
btn1=document.getElementById("btn1");
btn2=document.getElementById("btn2");
btn1.onclick=function(){if(int!=null){clearInterval(int);}//如果int里面有数值,那一定是存在最新的一个定时器int=setInterval('console.log(2)',400);
}
btn2.onclick=function(){clearInterval(int);int=null;
}
</script>
值得注意的是,在上面的代码中,存储计时器的id值的int都是全局变量,所以它一直存储着最新创建的计时器的id值。
但是,如果我们把这段代码改写成:
btn1.onclick=function(){var int=setInterval(function(){console.log(int);},400);
}
把int用var声明成局部变量后,每次执行定时器中的function时,机会把当前计时器对应的id值赋值给int,也就是这个id存储的又是当前运行的计时器了。
比如我点了两下开始,每隔400ms就是id为2的定时器起一下作用,id为3的定时器起一下作用.所以就间隔着打印出23232323232323的值了。
关于定时器setInterval()累加或者是重叠的问题相关推荐
- 前端定时器 setInterval 和 setTimeout
前端定时器 setInterval 和 setTimeout 1.setInterval 循环执行 设置循环执行 销毁定时器 2.setTimeout 定时执行 设置定时执行 3. setTimeou ...
- Vue中使用定时器setInterval和延迟执行setTimeout
js中定时器有两种,一个是循环执行setInterval,另一个是定时执行setTimeout 一.循环执行(setInterval) 顾名思义,循环执行就是设置一个时间间隔,每过一段时间都会执行一次 ...
- js 解决页面切换时,定时器setInterval 会变得越来越慢
在项目中经常会用到自定义动画或者自定义一些无缝滚动什么的,需要用到js中的定时器setinterval,但是,楼主发现在项目中测试的时候,切换页面或者浏览器上面的页签时,定时器明明没有收到干扰,但是页 ...
- js 定时器setInterval
定时器setInterval 1.setInterval开启定时器 2.关闭定时器 3.小练习:自动切换图片 1.setInterval开启定时器 * setInterval()* - 定时调用* - ...
- vue中使用定时器setInterval
vue中使用定时器setInterval this.timer = setInterval(this.fetchData, 1000);clearInterval(this.timer);before ...
- nodejs定时器setInterval,setTimeout,clearTimeout, clearInterval源码学习
nodejs Timer nodejs Timer timer.unref()的失效情况 先看timer.unref的底层调用 对失效的解释 定时器的创建 TimerWrap TimerWrap() ...
- Jquery中使用定时器setInterval和setTimeout
直接在ready中调用其他方法,会提示缺少对象的错误,解决方法如下: 方法1. 函数不在$(function(){....})内,setInterval第一个参数为"showAtuto&qu ...
- 的setinterval函数_Vue定时器与JS 定时器 setInterval() 和 setTimeout()
H5前端开发社区专注更多编程教程和电子书天天在用钱在vue中,有两套定时器,一套是浏览器API,window对象上的:另一套就是vue/nodejs封装的,需要引入 import { setInter ...
- js定时器介绍:倒计时定时器setTimeout、间隔定时器setInterval
1.定时器介绍 在js里面,有两种定时器:倒计时定时器和间隔定时器 (1)倒计时定时器:倒计时多长时间以后执行函数 语法:setTimeout(要执行的函数,多长时间以后执行) <script ...
- js 解决页面切换时,定时器setInterval会变得很慢,有时候不执行的问题
通过浏览器窗口焦点事件,清掉定时器 window.onfocus=function(){timer=setInterval(autoRun,1000); }window.onblur=function ...
最新文章
- ORA-03135 ,ORA-02050到底什么原因?
- dubbo-admin构建问题总结
- erlang-17版本的编码方式
- C# 图片、文件等加入Project Resources
- Android一个自定义的进度环:ProgressChart
- YOLOv3改进方法增加特征尺度和训练层数
- 线性表java实现之顺序存储源码
- android studio for android learning (八)开机启动界面splashActivity
- java面向对象是什么意思_java什么是面向对象
- IDEA登录LeetCode插件失败
- 微服务SpringBoot整合Jasypt加密工具
- php期末作业总结,期末考试总结与反思(精选6篇)
- 张博增是谁?为什么说他开启石墨烯的2.0时代!
- ARM学习笔记:HC-SR501人体红外传感器
- 第八代小冰年度发布会召开,开启小冰智能生涯
- ---- 招聘之操作系统原理 ----
- 计划评审方法和关键路线法【PERT/CPM、统筹方法】
- 【2018慢性病与信息大会】孔飞:信息交互在智能健康中的应用
- 中国排行前十的服务器供应商
- Android指纹识别ui显示,Android9.0指纹识别BiometricPrompt的简单使用