JavaScript之節流與防抖

我的博客原文地址git

背景

咱們在開發的過程當中會常常使用如scroll、resize、touchmove等事件,若是正常綁定事件處理函數的話,有可能在很短的時間內屢次連續觸發事件,十分影響性能。
所以針對這類事件要進行節流或者防抖處理github

節流

節流的意思是,在規定的時間內只會觸發一次函數,如咱們設置函數500ms觸發一次,以後你不管你觸發了多少次函數,在這個時間內也只會有一次執行效果app

先來看一個例子函數

https://codepen.io/wclimb/pen...性能

咱們看到使用了節流的在1000ms內只觸發了一次,而沒有使用節流的則頻繁觸發了調用的函數this

接下來看看代碼實現
v1 第一次不觸發,不傳參實現code

function throttle(fn,interval){
    var timer;
    return function(){
        if(timer){
            return
        }
        timer = setTimeout(() => {
            clearTimeout(timer)
            timer = null
            fn()
        }, interval || 1000);
    }   
}

效果是實現了,可是我在嘗試在執行函數裏console.log(this),結果發現this指向的是window,並且還發現咱們不能傳遞參數,下面就來改進一下事件

v2 第一次觸發函數,接收參數ip

function throttle(fn,interval){
    var timer,
        isFirst = true;
    return function(){
        var args = arguments,
            that = this;
        if(isFirst){
            fn.apply(that,args)
            return isFirst = false
        }
        if(timer){
            return
        }
        timer = setTimeout(() => {
            clearTimeout(timer)
            timer = null
            fn.apply(that,args)
        }, interval || 1000);
    }   
}

防抖

防抖的意思是不管你觸發多少次函數,只會觸發最後一次函數。最經常使用的就是在表單提交的時候,用戶可能會一段時間內點擊不少次,這個時候能夠增長防抖處理,咱們只須要最後一次觸發的事件開發

先來看一個例子

https://codepen.io/wclimb/pen...

咱們看到使用了防抖的方框,不管你在裏面觸發了多少次函數,都只會觸發最後的那一次函數,而沒有使用防抖的則頻繁觸發了調用的函數

v1 第一次不觸發函數

function debounce(fn,interval){
    var timer;
    return function(){
        var args = arguments,
            that = this;
        if(timer){
            clearTimeout(timer)
            timer = null
        }
        timer = setTimeout(() => {
            fn.apply(null,args)
        }, interval || 1000);
    }
}

上面這段代碼仍然能夠正常執行,可是咱們並無指定他的this

v2 第一次就觸發函數

function debounce(fn,interval){
    var timer,
        isFirst  = true,
            can = false;
    return function(){
        var args = arguments,
            that = this;
        if(timer){
            clearTimeout(timer)
            timer = null
        }
        if(isFirst){
            fn.apply(that,args)
            isFirst = false
            setTimeout(() => {
                can = true
            }, interval || 1000);
        }else if(can){
            timer = setTimeout(() => {
                fn.apply(null,args)
            }, interval || 1000);
        }
    }
}

若有雷同,純屬抄我(開玩笑)

若有錯誤,還望指正,僅供參考

GitHub:wclimb

相關文章
相關標籤/搜索