防抖和節流簡介

2021-10-07 16:17:43 字數 1711 閱讀 6959

背景:近期經常被問到防抖和節流,之前專案中也有遇到並且解決過,猛地一問這麼專業的術語如果之前沒有聽過還真容易發蒙,因此簡單整理一下,希望對需要的小夥伴們有所幫助。

1.判斷回到頂部按鈕的顯示時機,一般需求是當頁面滑動距離頂部一定距離之後才需要顯示,此時我們一般只需要監聽瀏覽器滾動事件,返回當前滾動條與頂部的距離。**如下:

function showtop  () 

window.onscroll = showtop

但是,實際執行會發現乙個問題,這個函式執行頻率特別高,這樣比較浪費效能,為了優化我們一般會用到防抖來處理。

3.頁面resize事件,常見於需要做頁面適配的時候。需要根據最終呈現的頁面情況進行dom渲染(這種情形一般是使用防抖,因為只需要判斷最後一次的變化情況)。

針對第一種場景,我們可以這麼思考:在第一次觸發事件時,不立即執行函式,而是給出乙個期限值eg:1000ms,然後:

a.如果在1000ms內沒有再次觸發滾動事件,那麼就執行函式;

b.如果在1000ms內再次觸發了滾動事件,那麼當前的計時器清零,重新開始計時。

結果:如果在我們設定的期限值內大量觸發同一事件,只會執行一次函式。

實現:我們使用settimeout來實現計時,由於需要用到變數,為了避免全部變數帶來汙染,使用閉包來實現,**如下:

function debounce(fn,delay)

timer = settimeout(fn,delay) // 簡化寫法

}}// 然後是監聽滾動位置的函式

function showtop ()

window.onscroll = debounce(showtop,1000) // 為了方便觀察效果我們取個大點的間斷值,實際使用根據需要來配置

以上**實現了防抖功能,也就是滾動條停止滾動1秒以上,才會執行函式,列印出滾動條距離頂部的數值。

防抖定義整理:對於短時間內連續觸發的事件(滾動監聽),防抖的含義就是讓某個時間期限(如上面的1000毫秒)內,事件處理函式只執行一次。

以上處理方法,也可能會遇到一些問題,比如如果一直按住滑鼠一直滾動,這樣的話就不會輸出我們想要的距離頂部的值,那這個應該怎麼解決呢?下面簡單說下節流(throttle)。

解決上面問題的方法的思路是,即使一直不斷觸發滾動條,我們也能在某個時間間隔後輸出間距值,這時候我們可以設計乙個類似開關的定期開放的函式,意思是我們讓乙個函式執行一次後,在某個時間段內暫時無效,過了這段時間再重新生效,具體**如下:

function throttle(fn,delay)

// 可用時間,執行函式並且在間隔期內把狀態位設為無效

valid = false

settimeout(() => , delay)

}}/* 請注意,節流函式還可以有以下思路實現

例如可以完全不借助settimeout,可以把狀態位換成時間戳,然後利用時間戳差值是否大於指定間隔時間來做判定。

也可以直接將settimeout的返回的標記當做判斷條件-判斷當前定時器是否存在,如果存在表示還在冷卻,並且在執行fn之後消除定時器表示啟用

*/// 監聽滾動條的滾動函式

function showtop ()

window.onscroll = throttle(showtop,1000)

以上**解決了防抖帶來的問題,如果一直拖著滾動條,也會以1s的時間間隔,持續輸出當前位置距離頂部的距離。

防抖和節流簡介

當事件被頻繁觸發時,不想讓其頻繁執行事件處理函式的一種解決方案。該方案通過設定乙個週期延遲執行動作,如果週期內又被重新觸發,則重新設定週期,直到週期結束,執行動作。節流的方案是通過設定乙個週期,在週期內只執行一次,如果在週期內重新觸發事件,則不執行。乙個週期結束後,開始新的週期。頻繁觸發事件會占用較...

簡介 js 防抖和節流

前端 js 日常開發中,在頁面滑鼠移動 mousemove,或視窗的 resize scroll,輸入框內容校驗等高頻操作時,如果事件處理函式呼叫的頻率無限制,會加重瀏覽器的負擔,如果處理不當或放任不管很容易引起瀏覽器卡死,導致使用者體驗非常差。此時我們可以採用 debounce 防抖 和 thro...

防抖和節流 什麼是防抖和節流

目錄二 節流 有這樣一種情況,想象有乙個表單,點選提交按鈕就傳送請求給伺服器。如果使用者在很短的時間間隔內 手抖 點選了多次,又或者是惡意點選,那麼就將傳送多個請求。該行為將造成伺服器額外的不必要負載。所謂防抖,實際上就是是處理這種常見的情況的描述。submit該段 當點選submit按鈕的時候,將...