JS定時器:setTimeout()和setInterval()方法

2020-07-16 10:05:09
在 JavaScript 中,window 物件包含 4 個定時器專用方法,說明如下表所示,使用它們可以實現程式碼定時執行,或者延遲執行,使用定時器可以設計演示動畫。

window 物件定時器方法列表
方法 說明
setInterval() 按照執行的週期(單位為毫秒)呼叫函數或計算表示式
setTimeout() 在指定的毫秒數後呼叫函數或計算表示式
clearInterval() 取消由 setInterval() 方法生成的定時器
clearTimeout() 取消由 setTimeout() 方法生成的定時器

setTimeout() 方法

setTimeout() 方法能夠在指定的時間段後執行特定程式碼。用法如下:

var o = setTimeout(code, delay);

引數 code 表示要延遲執行的字串型程式碼,將在 Windows 環境中執行,如果包含多個語句,應該使用分號進行分隔。delay 表示延遲時間,以毫秒為單位。

該方法返回值是一個 Timer ID,這個 ID 編號指向延遲執行的程式碼控制控制代碼。如果把這個控制代碼傳遞給 clearTimeout() 方法,則會取消程式碼的延遲執行。

範例1

下面範例演示了當滑鼠指標移過段落文字時,會延遲半秒鐘彈出一個提示對話方塊,顯示當前元素的名稱。
<p>段落文字</p>
<script>
    var p = document.getElementsByTagName("p") [0];
    p.onmouseover = function (i) {
        setTimeout (function () {
            console.log(p.tagName);
        }, 500);
    }
</script>
setTimeout() 方法的第一個引數雖然是字串,但是也可以是一個函數。一般建議把函數作為引數傳遞給 setTimeout() 方法,等待延遲呼叫。

範例2

下面範例演示了如何為集合中每個元素都系結一個事件延遲處理常式。
var o = document.getElementsByTagName("body") [0].childNodes;  //獲取body下所有子元素
for (var i = 0; i < o.length; i ++){  //遍歷元素集合
    o[i].onmouseover = function (i) {  //註冊滑鼠經過事件處理常式
        return function () {  //返回閉包函數
            f (o[i]);  //呼叫函數f,並傳遞當前物件參照
        }
    } (i);  //呼叫函數並傳遞迴圈序號,實現在閉包中儲存物件序號值
}
function f (o) {  //延遲處理常式
    var out = setTimeout (function () {
        console.log(o.tagName);  //顯示當前元素的名稱
    }, 500}  //定義延遲半秒鐘後執行程式碼
}
這樣當滑鼠指標移過每個頁面元素時,都會在延遲半秒鐘後彈出一個提示對話方塊,提示元素名稱。

範例3

可以利用 clearTimeout() 方法在特定條件下清除延遲處理程式碼。例如,當滑鼠指標移過某個元素,停留半秒鐘之後才會彈出提示資訊,一旦滑鼠指標移出當前元素,就立即清除前面定義的延遲處理常式,避免干擾。
var o = document.getElementsByTagName("body") [0].childNodes;
for (var i = 0; i < o.length; i ++ ) {
    o[i].onmouseover = function (i) {  //為每個元素注冊滑鼠移過時事件延遲處理常式
        return function () {
            f (o[i]);
        }
    } (i);
    o[i].onmouseover = function (i) {  //為每個元素注冊滑鼠移出時清除延遲處理常式
        return function () {
            clearTimeout (o[i].out);  //清除已註冊的延遲處理常式
        }
    } (i);
}
function f (o) {  //把延遲處理定時器儲存在每個元素的 out 屬性中
    o.out = setTimeout (function () {
        nsole.log(o.tagName);
    }, 500);
}
如果希望反復執行 setTimeout() 方法中包含的程式碼,可以在 setTimeout() 方法中包含對自身的呼叫,這樣就可以把自身註冊為可以被反復執行的方法。

範例4

下面範例會在頁面內的文字方塊中按秒針速度顯示遞加的數位,當迴圈執行 10 次後,會呼叫 clearTimeout() 方法清除對程式碼的執行,並彈出提示資訊。
<input type="text" />
<script>
    var t = document.getElementsByTagName("input") [0];
    var i = 1;
    function f () {
        var out = setTimeout(  //定義延遲執行的方法
        function () {  //延遲執行函數
            t.value = i ++;  //遞加數位
            f ();  //呼叫包含setTimeout()方法的函數
        }, 1000);  //設定每秒執行一次呼叫
        if (i > 10) {  //如果超過10次,則清除執行,並彈出提示資訊
            clearTimeout (out);
            console.log("10秒鐘已到");
        }
    }
    f();  //呼叫函數
</script>

setInterval() 方法

setInterval() 方法能夠周期性執行指定的程式碼,如果不加以處理,那麼該方法將會被持續執行,直到瀏覽器視窗關閉或者跳轉到其他頁面為止。用法如下:

var o = setInterval (code, interval)

該方法的用法與 setTimeout() 方法基本相同,其中引數 code 表示要週期執行的程式碼字串,引數 interval 表示週期執行的時間間隔,以毫秒為單位。

該方法返回值是一個 Timer ID,這個 ID 編號指向對當前週期函數的執行參照,利用該值對計時器進行存取,如果把這個值傳遞給 clearTimeout() 方法,則會強制取消週期性執行的程式碼。

如果 setInterval() 方法的第 1 個引數是一個函數,則 setInterval() 方法可以接收任意多個引數,這些引數將作為該函數的引數使用。格式如下:

var o = setInterval(functioin, interval[,arg1, arg2, ... argn])

範例5

針對範例 4 可以按以下方法進行設計。
<input type="text" />
<script>
    var t = document.getElementByTagName("input") [0];
    var i = 1;
    var out = setInterval (f, 1000);  //定義周期性執行的函數
    function f () {
        t.value = i ++;
        if (i > 10) {  //如果重複執行10次
            clearTimeout (out);  //則清除周期性呼叫函數
            console.log("10秒鐘已到");
        }
    }
</script>
setTimeout() 方法主要用來延遲程式碼執行,而 setInterval() 方法主要實現週期性執行程式碼。它們都可以設計週期性動作,其中 setTimeout() 方法適合不定時執行某個動作,而 setInterval() 方法適合定時執行某個動作。

setTimeout() 方法不會每隔固定時間就執行一次動作,它受 JavaScript 任務佇列的影響,只有前面沒有任務時,才會按時延遲執行動作。而 setInterval() 方法不受任務佇列的限制,它只是簡單的每隔一定的時間就重複執行一次動作,如果前面任務還沒有執行完畢,setInterval()  可能會插隊按時執行動作。