当给一个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()累加或者是重叠的问题相关推荐

  1. 前端定时器 setInterval 和 setTimeout

    前端定时器 setInterval 和 setTimeout 1.setInterval 循环执行 设置循环执行 销毁定时器 2.setTimeout 定时执行 设置定时执行 3. setTimeou ...

  2. Vue中使用定时器setInterval和延迟执行setTimeout

    js中定时器有两种,一个是循环执行setInterval,另一个是定时执行setTimeout 一.循环执行(setInterval) 顾名思义,循环执行就是设置一个时间间隔,每过一段时间都会执行一次 ...

  3. js 解决页面切换时,定时器setInterval 会变得越来越慢

    在项目中经常会用到自定义动画或者自定义一些无缝滚动什么的,需要用到js中的定时器setinterval,但是,楼主发现在项目中测试的时候,切换页面或者浏览器上面的页签时,定时器明明没有收到干扰,但是页 ...

  4. js 定时器setInterval

    定时器setInterval 1.setInterval开启定时器 2.关闭定时器 3.小练习:自动切换图片 1.setInterval开启定时器 * setInterval()* - 定时调用* - ...

  5. vue中使用定时器setInterval

    vue中使用定时器setInterval this.timer = setInterval(this.fetchData, 1000);clearInterval(this.timer);before ...

  6. nodejs定时器setInterval,setTimeout,clearTimeout, clearInterval源码学习

    nodejs Timer nodejs Timer timer.unref()的失效情况 先看timer.unref的底层调用 对失效的解释 定时器的创建 TimerWrap TimerWrap() ...

  7. Jquery中使用定时器setInterval和setTimeout

    直接在ready中调用其他方法,会提示缺少对象的错误,解决方法如下: 方法1. 函数不在$(function(){....})内,setInterval第一个参数为"showAtuto&qu ...

  8. 的setinterval函数_Vue定时器与JS 定时器 setInterval() 和 setTimeout()

    H5前端开发社区专注更多编程教程和电子书天天在用钱在vue中,有两套定时器,一套是浏览器API,window对象上的:另一套就是vue/nodejs封装的,需要引入 import { setInter ...

  9. js定时器介绍:倒计时定时器setTimeout、间隔定时器setInterval

    1.定时器介绍 在js里面,有两种定时器:倒计时定时器和间隔定时器  (1)倒计时定时器:倒计时多长时间以后执行函数 语法:setTimeout(要执行的函数,多长时间以后执行) <script ...

  10. js 解决页面切换时,定时器setInterval会变得很慢,有时候不执行的问题

    通过浏览器窗口焦点事件,清掉定时器 window.onfocus=function(){timer=setInterval(autoRun,1000); }window.onblur=function ...

最新文章

  1. ORA-03135 ,ORA-02050到底什么原因?
  2. dubbo-admin构建问题总结
  3. erlang-17版本的编码方式
  4. C# 图片、文件等加入Project Resources
  5. Android一个自定义的进度环:ProgressChart
  6. YOLOv3改进方法增加特征尺度和训练层数
  7. 线性表java实现之顺序存储源码
  8. android studio for android learning (八)开机启动界面splashActivity
  9. java面向对象是什么意思_java什么是面向对象
  10. IDEA登录LeetCode插件失败
  11. 微服务SpringBoot整合Jasypt加密工具
  12. php期末作业总结,期末考试总结与反思(精选6篇)
  13. 张博增是谁?为什么说他开启石墨烯的2.0时代!
  14. ARM学习笔记:HC-SR501人体红外传感器
  15. 第八代小冰年度发布会召开,开启小冰智能生涯
  16. ---- 招聘之操作系统原理 ----
  17. 计划评审方法和关键路线法【PERT/CPM、统筹方法】
  18. 【2018慢性病与信息大会】孔飞:信息交互在智能健康中的应用
  19. 中国排行前十的服务器供应商
  20. Android指纹识别ui显示,Android9.0指纹识别BiometricPrompt的简单使用

热门文章

  1. 简单计算机组成原理,计算机组成原理简单总结(一)
  2. 开发中常用正则表达式
  3. iOS开发之HTTP与HTTPS网络请求
  4. extern 关键字详解
  5. asp.net 读取导入的project(mpp)文件
  6. 《Android开发卷——HTTP网络通信,HTTP网络连接》
  7. Netty基于ip的黑名单过滤——RuleBasedIpFilter
  8. Java web项目的解耦合
  9. Spring BeanFactory和FactoryBean的区别
  10. Java数组去掉重复的方法集