zoukankan      html  css  js  c++  java
  • 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.欢迎小伙伴交流这一问题~

     

        

  • 相关阅读:
    VC多文档编程技巧(取消一开始时打开的空白文档)
    GetActiveView 返回 NULL 为 MDI 框架窗口
    UC何小鹏:移动互联网创业需警惕五大“不靠谱
    vc:如何从Internet上有效而稳定地下载文件
    python操作文件
    python if条件判断
    python使用退格键时出现^H解决方法
    Python中列表,元组,字典,集合的区别
    python调用shell脚本
    python调用shell命令
  • 原文地址:https://www.cnblogs.com/johnnyzen/p/7282116.html
Copyright © 2011-2022 走看看