js防抖 和節流函式

泥猴桃發表於2018-12-20

最近搞了一個input 輸入框 自動完成的效果
大概效果如下連結:
http://www.jq22.com/jquery-info438
然後我是用keyup() 方法監聽的input 輸入框的值,只要鍵盤抬起就會去請求介面!所以啊,頻率太快,噁心至極。所以要想辦法搞丫的一下。不然看著太難受。也影響效能!
突然想起來 vue 的官網上有一個小案例,就是大概這個效果,輸入內容的時候不去請求,等輸入停下以後,才會去請求,
https://cn.vuejs.org/v2/guide/computed.html 效果在頁面最底部,
但是他用的是 Lodash 的 _.debounce 函式來限制的頻率操作。而我做的是一個很小的效果,感覺大材小用了(其實是懶)。
有了眉目 順藤摸瓜,百度一番後瞭解到了 防抖和節流這兩個概念。然後在網上找到了下邊的兩個方法記錄下來

先普及下概念

函式防抖(debounce):當持續觸發事件時,一定時間段內沒有再觸發事件,事件處理函式才會執行一次,如果設定的時間到來之前,又一次觸發了事件,就重新開始延時。

不有的想起了一個場景,

輸入框內容校驗 ,類似百度聯想詞
通過監聽 scroll 事件,檢測滾動位置,根據滾動位置顯示返回頂部按鈕
通過監聽 resize 事件,對某些自適應頁面調整DOM的渲染(通過CSS實現的自適應不再此範圍內)
通過監聽 keyup 事件,監聽文字輸入並呼叫介面進行模糊匹配

函式節流(throttle):當持續觸發事件時,保證一定時間段內只呼叫一次事件處理函式。

在來個不由得想起了一個場景,說這話的時候多少有點尷尬。

搶購的時候。

畫外音:任何脫離了業務場景的技術都是耍流氓,防抖也好,節流也罷,適合他的業務場景才是最好的

分析需求。

防抖:我們應該封裝一個函式,這個函式需要哪些引數,看上邊概念的兩個關鍵字:一定時間(delay),處理函式(fn)。

function debounce(fn, dealy) {
         let timer = null
         return function () {
             //上來的給他清理掉哦,感興趣的同學可以去研究下setTimeout(),和 
             // clearTimeout
             clearTimeout(timer)
             //在這個時間內我只呼叫一次事件處理函式,是不是達到防抖的目的呢。
             timer = setTimeout(function () {
                 fn.apply(this, arguments)
             }, dealy)
         }
     }
    // 功能實現,800ms之內,你觸發多少次我只執行一次,就是這麼任性
    input.oninput = debounce(fn,800)

節流:我們還是應該封裝一個函式,需要引數,事件處理函式(fn),一定時間(wait)

function throttle(fn, wait) {
         //定義一個事件為0,第一次肯定會執行
         let lastTime = 0
         return function () {
             //拿到從1970年到現在的時間戳
             let nowTime = new Date.getTime()
             //在這個時間內我才觸發事件處理函式,是不是起到節流的目的呢。
             if (nowTime - lastTime > wait) {
                 fn.apply(this, arguments)
                 lastTime = nowTime
             }
         }
     }
     //功能實現,不好意思,300ms這個時間之內,點選我多少次,我就給你處理一次,sorry
     button.click = throttle(fn,300)

最後發現用keyup 來監聽input 輸入框的內容實在是有點不合適, 想到了 js 原生的 oninput() 方法
教程 網址: http://www.runoob.com/jsref/event-oninput.html
jq 有響應的bind() 的方法可以繫結 oninput 但是有網友說相容性不太好,建議還是用原生的oninput() 方法

相關文章