[JavaScript] 小结:关闭轮询定时器(setTimeout/clearTimeout|setInterval/clearInterval)
已知:
1.1 开启Timeout程序: scope.setTimeout("functionName()" | functionHandle, timeValue) 返回值:timerID
1.2 关闭Timeout程序: scope.clearTimeout(timerID);
2.1 开启Interval程序: scope.setInterval("functionName()" | functionHandle, timeValue) 返回值:timerID
2.2 关闭Interval程序: scope.clearInterval(timerID);
一、背景
在替实验室小伙伴解决问题过程中,出现了这样一个问题:
她用网页做了一个轮播图,利用不断地轮询setTimeout + 切换被轮播图片的css属性opacity:0/1来达到轮播效果;
当网页加载后,图片轮播自动执行;当用户鼠标移动到图片轮播区域上时,立即停止轮播(即 清除 setTimeout定时器),而不是继续轮播图片(使用户看不到想看的图片内容,提高用户体验);
然而,在全局域中,使用clearTimeout()方法可以实现,但在鼠标触发事件的函数内部调用,却失败,百思不得其解!(这个问题,实际上本文并没有解决!)
为了解决这个需求,我模拟了这一个过程,并对setTimeout轮询方法与图片轮播的方法进行解耦(分离成为两个函数),然后在封装的轮询定时器Timer中依次调用图片轮播方法和setTimeout方法,同时在轮询过程中,总是记录最近(最后)一次setTimeout方法返回的timerID值,这一点很重要;
最后:当鼠标滑过目标区域时,通过记录的最后一次timerID和clearTimeeout值来关闭图片轮播整个轮询。
【原理:即关闭最后一次(也是程序执行的最近一次)循环的timeID,使循环停止】
二、源码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>demo setTimeout & clearTimeout</title> </head> <body> <ul> <li><a href="#"><input type="number" value="0"></a></li> <li><a href="#"><input type="number" value="1"></a></li> </ul> <script type="text/javascript"> var aNodes = document.getElementsByTagName("a"); var inputNodes = document.getElementsByTagName("input"); //console.log('test:aNodes ' + aNodes.length); var changeNum = function(){ inputNodes[0].value = parseInt(inputNodes[0].value) + 1; }; var a1_timeoutId; var timeIds = -1; var changeNumByTimer = function(){ // a1_timeoutId = setTimeout(function(){ changeNum(); var timeKey = setTimeout("changeNumByTimer()",1000); timeIds = timeKey; console.log('test:当前的timeID:' + timeKey); // timeIds.push(timeKey); // setTimeout(changeNum,1000); // },1000); } changeNumByTimer(); //当鼠标滑过 aNodes[0].onmouseover = function(){ console.log('test:aNodes[0].onmouseover:' + "鼠标滑过a链接[0]"); console.log('test:aNodes[0].onmouseover: timeIds ' + timeIds); // for(var i = 0; i < timeIds.length; i++){ // // clearTimeout(timeIds[i]); // // console.log('test: 已经关闭了 timeID:' + timeIds[i]); // //clearTimeout(timeIds[timeIds.length-1]); // //console.log('test: 已经关闭了 timeID:' + timeIds[timeIds.length-1]); // } clearTimeout(timeIds); console.log('test: 已经关闭了 timeID:' + timeIds); } </script> </body> </html>
三、效果
四、总结
1.成功解决了需求的技术问题。
2.其实并没有解决我们最初的问题:
2.1 为什么全局域中可以关闭,而在onmouseover(鼠标滑过事件)函数中无法关闭的问题
3.参考文档:
MDN:https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval
4.欢迎小伙伴交流这一问题~
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!