函數防抖和節流

函數防抖

定義:bash

屢次觸發事件後,事件處理函數只執行一次,而且是在觸發操做結束時執行。app

原理:函數

對處理函數進行延時操做,若設定的延時到來以前,再次觸發事件,則清除上一次的延時操做定時器,從新定時。oop

scorll簡單例子:性能

let timer;
window.onscroll  = function () {
    if(timer){
        clearTimeout(timer)
    }
    timer = setTimeout(function () {
        //滾動條位置
        let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
        console.log('滾動條位置:' + scrollTop);
        timer = undefined;
    },200)
}
複製代碼

防抖函數的封裝:ui

/**
 * 防抖函數
 * @param method 事件觸發的操做
 * @param delay 多少毫秒內連續觸發事件,不會執行
 * @returns {Function}
 */
function debounce(method,delay) {
    let timer = null;
    return function () {
        let self = this,
            args = arguments;
        timer && clearTimeout(timer);
        timer = setTimeout(function () {
            method.apply(self,args);
        },delay);
    }
}

window.onscroll = debounce(function () {
    let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log('滾動條位置:' + scrollTop);
},200)
複製代碼

函數防抖的適用性:this

經過函數防抖,解決了屢次觸發事件時的性能問題spa

好比,咱們在監聽滾動條位置,控制是否顯示返回頂部按鈕時,就能夠將防抖函數應用其中。code

當咱們作圖片懶加載(lazyload)時,須要經過滾動位置,實時顯示圖片時,若是使用防抖函數,懶加載(lazyload)函數將會不斷被延時,事件

只有停下來的時候纔會被執行,對於這種須要實時觸發事件的狀況,就顯得不是很友好了。

函數節流

函數節流,經過設定時間片,控制事件函數間斷性的觸發。

定義:

觸發函數事件後,短期間隔內沒法連續調用,只有上一次函數執行後,過了規定的時間間隔,才能進行下一次的函數調用

原理:

對處理函數進行延時操做,若設定的延時到來以前,再次觸發事件,則清除上一次的延時操做定時器,從新定時。

scorll簡單例子:

let startTime = Date.now(); //開始時間
let time = 500; //間隔時間
let timer;
window.onscroll = function throttle(){
    let currentTime = Date.now();
    if(currentTime - startTime >= time){
        let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
        console.log('滾動條位置:' + scrollTop);
        startTime = currentTime;
    }else{
        clearTimeout(timer);
        timer = setTimeout(function () {
            throttle()
        }, 50);
    }
}
複製代碼

節流函數的封裝:

/**
 * 節流函數
 * @param method 事件觸發的操做
 * @param mustRunDelay 間隔多少毫秒須要觸發一次事件
 */
function throttle(method, mustRunDelay) {
    let timer,
        args = arguments,
        start;
    return function loop() {
        let self = this;
        let now = Date.now();
        if(!start){
            start = now;
        }
        if(timer){
            clearTimeout(timer);
        }
        if(now - start >= mustRunDelay){
            method.apply(self, args);
            start = now;
        }else {
            timer = setTimeout(function () {
                loop.apply(self, args);
            }, 50);
        }
    }
}
window.onscroll = throttle(function () {
    let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log('滾動條位置:' + scrollTop);
},800)
複製代碼
相關文章
相關標籤/搜索