函數節流和函數去抖,前端鎖(防止點擊、滾動、拖拽等事件多次觸發)

throttle(函數節流) debounce(函數去抖 mutex(鎖)

Java等很多語言都有”鎖機制“,其實前端開發很多時候也需要“鎖”。例如:用戶連續點擊按鈕會多次觸發click事件、監聽鼠標滾動事件、監聽input框輸入事件...等都會需要“鎖”。今天,我就整理了有關前端“鎖”的相關知識,以供大家參考!

函數節流和去抖的出現場景,一般都伴隨着客戶端 DOM 的事件監聽。舉個例子,實現一個原生的拖拽功能(不能用 H5 Drag&Drop API),需要一路監聽 mousemove 事件,在回調中獲取元素當前位置,然後重置 dom 的位置(樣式改變)。如果我們不加以控制,每移動一定像素而觸發的回調數量是會非常驚人的,回調中又伴隨着 DOM 操作,繼而引發瀏覽器的重排與重繪,性能差的瀏覽器可能就會直接假死,這樣的用戶體驗是非常糟糕的。我們需要做的是降低觸發回調的頻率,比如讓它 500ms 觸發一次,或者 200ms,甚至 100ms,這個閾值不能太大,太大了拖拽就會失真,也不能太小,太小了低版本瀏覽器可能就會假死,這樣的解決方案就是函數節流,英文名字叫「throttle」。函數節流的核心是,讓一個函數不要執行得太頻繁,減少一些過快的調用來節流。

說完函數節流,再看它的好基友函數去抖(debounce)。思考這樣一個場景,對於瀏覽器窗口,每做一次 resize 操作,發送一個請求,很顯然,我們需要監聽 resize 事件,但是和 mousemove 一樣,每縮小(或者放大)一次瀏覽器,實際上會觸發 N 多次的 resize 事件,用節流?節流只能保證定時觸發,我們一次就好,這就要用去抖。簡單的說,函數去抖就是對於一定時間段的連續的函數調用,只讓其執行一次。

throttle 應用場景

函數節流有哪些應用場景?哪些時候我們需要間隔一定時間觸發回調來控制函數調用頻率?

  • DOM 元素的拖拽功能實現(mousemove)
  • 射擊遊戲的 mousedown/keydown 事件(單位時間只能發射一顆子彈)
  • 計算鼠標移動的距離(mousemove)
  • Canvas 模擬畫板功能(mousemove)
  • 搜索聯想(keyup)
  • 監聽滾動事件判斷是否到頁面底部自動加載更多:給 scroll 加了 debounce 後,只有用戶停止滾動後,纔會判斷是否到了頁面底部;如果是 throttle 的話,只要頁面滾動就會間隔一段時間判斷一次 #21 (comment)

debounce 應用場景

函數去抖有哪些應用場景?哪些時候對於連續的事件響應我們只需要執行一次回調?

  • 每次 resize/scroll 觸發統計事件
  • 文本輸入的驗證(連續輸入文字後發送 AJAX 請求進行驗證,驗證一次就好)

小結

函數節流和函數去抖的核心其實就是限制某一個方法被頻繁觸發,而一個方法之所以會被頻繁觸發,大多數情況下是因爲 DOM 事件的監聽回調,而這也是函數節流以及去抖多數情況下的應用場景。函數節流:間隔時間段觸發一次,函數去抖:只觸發一次,兩者有時候不需要細分,節流去抖也可以合在一起。

解決方法

   方法一:加鎖

阻止連續點擊事件:申明一個變量,點擊時置灰提交按鈕。等接口調用結束放開按鈕。

<template>
<div>
    <!-- 其他代碼 -->
    <button v-if="canSave" @click="save">提交</button>
    <button v-else disabled>提交</button>
</div>
</template>
<script>
export default {
    data(){
        return {
            canSave: true,
        }
    },
    methods: {
        save(){
            if(!canSave){
                return;
            }
            this.canSave = false;
            // AJAX 結束後 this.canSave = true;
        },
    }
}
</script>

方法二:

throttle-debounce 插件

相關網址資料:https://segmentfault.com/q/1010000015296510

https://github.com/lessfish/underscore-analysis/issues/21

https://github.com/lessfish/underscore-analysis/issues/20

整合了一下資料,如有錯誤和問題,歡迎指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章