js 防抖與節流

1.防抖

觸發高頻事件後n秒內函數只會執行一次,若是n秒內高頻事件再次被觸發,則從新計算時間
var time = null;
document.onmousewheel = function(e){
    if (time) {
        clearTimeout(time)
    }
    time = setTimeout( () => {
        /* 進行滾動操做 */
        time = null
    }, 100)
}
# 第一次滑動時 time 是null ,直接執行 setTimeout ,在 0.1s 內若是又繼續滑動了滾輪,
# 就會清除上一次的 setTimeout ,直到在 0.1s 內沒有滑動滾輪,就會執行 setTimeout 中
# 的內容。

2. 節流

高頻事件觸發,但在n秒內只會執行一次,因此節流會稀釋函數的執行頻率

下面是js代碼,這種方式有點很差理解閉包

function throttle() {
    let canRun = true; // 經過閉包保存一個標記

    return function () {
        console.log(canRun)
        if (!canRun) return; // 在函數開頭判斷標記是否爲true,不爲true則return
        canRun = false; // 當即設置爲false
        setTimeout(() => { // 將外部傳入的函數的執行放在setTimeout中
            // 最後在setTimeout執行完畢後再把標記設置爲true(關鍵)表示能夠執行下一次循環了。
            // 當定時器沒有執行的時候標記永遠是false,在開頭被return掉
            console.log(1)
            canRun = true;
        }, 1000);
    };
}
window.addEventListener('resize', throttle());

# 當函數被註冊的時候,定義了 canRun 爲 true,以後返回一個函數,
# 每當事件被觸發的時候,執行返回的函數中的內容。首先判斷 canRun,
# 若是爲 true 就往下執行,而後設 canRun 爲 false,執行定時器,
# 在接下來的 1s 內,若是再次觸發 resize 事件,canRun 的值是 false ,
# 會直接 return 空,不會執行任何操做。當 1s 後執行了定時器中的
# 內容並設置 canRun 爲 true 後,觸發事件纔會從新執行定時器。

***注意***
    1. 在添加事件的時候,後面的函數是加()的。正由於這個括號,因此在註冊
       事件的時候,let canRun = true 會被執行一次,而在事件被觸發的時候,
       let canRun = true 是不會被執行的,只有在被註冊時會被執行一次。
    2. 觸發事件之後,執行的是 throttle 函數返回的函數,而不是 throttle 
       函數。

這兩種方式的區別:第一種是當 0.1s 內再次觸發事件,會消除定時器,從新計算,適用於滾輪滾動後頁面的切換。由於用戶滾輪切換頁面時,一次會滾動不少下;第二種是若是事件一直在觸發,可是每 1s 會執行一次。函數

相關文章
相關標籤/搜索