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.歡迎小伙伴交流這一問題~

 

 

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM