網站搜尋

javascript:清除所有超時?


有沒有辦法清除給定視窗的所有逾時?我猜這些逾時存放在 window 物件的某個地方,但無法確認。

任何跨瀏覽器的解決方案都歡迎。

答案#1

它們不在 window 物件中,但它們有 id,而且(據我所知)是連續的整數。

所以你可以這樣清除所有的超時:

var id = window.setTimeout(function() {}, 0);

while (id--) {
    window.clearTimeout(id); // will do nothing if no timeout with id is present
}

答案#2

我認為實現這一點最簡單的方法是將所有的 setTimeout 識別碼存儲在一個陣列中,這樣你就可以輕鬆地迭代並對它們全部使用 clearTimeout()。

var timeouts = [];
timeouts.push(setTimeout(function(){alert(1);}, 200));
timeouts.push(setTimeout(function(){alert(2);}, 300));
timeouts.push(setTimeout(function(){alert(3);}, 400));

for (var i=0; i<timeouts.length; i++) {
  clearTimeout(timeouts[i]);
}

答案#3

這真的很晚了……但是:

基本上,setTimeout/setInterval 的 ID 是依序排列的,所以只要建立一個虛擬的 timeout 函數來取得最高的 ID,然後清除所有比這個 ID 小的 interval 就可以了。

const highestId = window.setTimeout(() => {
  for (let i = highestId; i >= 0; i--) {
    window.clearInterval(i);
  }
}, 0);

答案#4

我對 Pumbaa80 的回答有一個補充,可能對開發舊版 IE 的人有用。

是的,所有主要瀏覽器都將超時 ID 實現為連續整數(規範並未要求這樣做)。雖然起始數字因瀏覽器而異。看起來 Opera、Safari、Chrome 以及 IE > 8 從 1 開始超時 ID,基於 Gecko 的瀏覽器從 2 開始,而 IE <= 8 則從一些隨機數字開始,這個數字在標籤頁刷新之間會神奇地保存下來。你可以自己發現它。

這意味著在 IE ≤8 中,while (lastTimeoutId--) 迴圈可能會運行超過 8 位數次,並顯示“此頁面上的腳本正在導致 Internet Explorer 運行緩慢”訊息。因此,如果你無法保存所有的 timeout id 或不想覆蓋 window.setTimeout,你可以考慮在頁面上保存第一個 timeout id,並清除 timeout 直到它。

在頁面早期加載時執行代碼:

var clearAllTimeouts = (function () {
    var noop = function () {},
        firstId = window.setTimeout(noop, 0);
    return function () {
        var lastId = window.setTimeout(noop, 0);
        console.log('Removing', lastId - firstId, 'timeout handlers');
        while (firstId != lastId)
            window.clearTimeout(++firstId);
    };
});

然後清除所有可能被外來代碼多次設置的待處理超時

答案#5

如何將超時 ID 儲存在全域陣列中,並定義一個方法將函數調用委派給 window 的方法。

GLOBAL={
    timeouts : [],//global timeout id arrays
    setTimeout : function(code,number){
        this.timeouts.push(setTimeout(code,number));
    },
    clearAllTimeout :function(){
        for (var i=0; i<this.timeouts.length; i++) {
            window.clearTimeout(this.timeouts[i]); // clear all the timeouts
        }
        this.timeouts= [];//empty the id array
    }
};