JS系列1---節流,去抖(防抖)應用場景:intput請求優化,頁面監聽

炫彩小zyy發表於2019-07-23

  在專案開發過程中經常遇到在input的change事件中發起請求,將使用者最新輸入的字元作為data傳給後臺,但是如果使用者的輸入頻率過高,或者使用者輸入的字元還未拼成一個完整的字詞,這時候發起請求會浪費網路資源,使頁面卡頓。

  這時候我們就用到了函式去抖(debounce)函式節流(throttle),首先來看一下概念:

  1,函式去抖(又稱防抖)

  在事件被觸發n秒後再執行回撥,如果在這n秒內又被觸發,則重新計時。

  未優化前程式碼demo:

        <input id="debounceTest" />
        <script>
            function ajax(value) {
              console.log(value+'-----------發起ajax請求')
            }
            
            let inputa = document.getElementById('debounceTest')
            
            inputa.addEventListener('keyup', function (e) {
                ajax(e.target.value)
            })
        </script>

  效果圖:

  

  從頁面中可以看到,只要觸發了keyup時間,頁面就會發起請求,不管使用者是否輸入了一個完整的字元,這樣對網路資源十分浪費,在移動端甚至可能造成使用者體驗不流暢,系統卡頓,所以我們來對程式碼進行優化,如下:

優化後程式碼demo:

function ajax(content) {
  console.log(content+'---------------ajax請求')
}

function debounce(fun, delay) {
    return function (args) {
        let that = this
        let _args = args
        clearTimeout(fun.id)
        fun.id = setTimeout(function () {
            fun.call(that, _args)
        }, delay)
    }
}
    
let inputb = document.getElementById('debounce')

let debounceAjax = debounce(ajax, 500)

inputb.addEventListener('keyup', function (e) {
        debounceAjax(e.target.value)
    })

  頁面效果:

  

  可以看出,當使用者一直在輸入時,頁面不會發起請求,當使用者的上次輸入與下次輸入有一定時間間隔時,頁面才會發起請求。

同樣的問題還有另一種解決方法:

2,函式節流(throttle)

     規定在一個單位時間內,只能觸發一次函式。如果這個單位時間內觸發多次函式,只有一次生效。

 還是上邊的例子,這次用節流的方法實現

節流後的程式碼demo:

function throttle(fun, delay) {
        let last, deferTimer
        return function (args) {
            let that = this
            let _args = arguments
            let now = +new Date()
            if (last && now < last + delay) {
                clearTimeout(deferTimer)
                deferTimer = setTimeout(function () {
                    last = now
                    fun.apply(that, _args)
                }, delay)
            }else {
                last = now
                fun.apply(that,_args)
            }
        }
    }

    let throttleAjax = throttle(ajax, 1000)

    let inputc = document.getElementById('throttle')
    inputc.addEventListener('keyup', function(e) {
        throttleAjax(e.target.value)
    })

頁面效果:

  可以看出,不管使用者的輸入速度是多少,頁面總是以恆定的間隔向後臺發起請求。

  函式節流還可以應用於其他事件,比如mouse移動事件,頁面滾動事件,resize事件等能高頻次觸發的事件中。

函式節流和去抖都是為了解決事件觸發頻率過高的問題,但是使用了不同的原理

節流是總是以固定的間隔發起請求,對高頻率事件做做次數限制。去抖是固定時間段內只傳送一次請求。對高頻率事件做做次數限制

  以上為節流去抖的全部內部,如有錯誤還望指正。

 

相關文章