防抖和節流嚴格算起來應該屬於效能優化的知識,但實際上遇到的頻率相當高,處理不當或者放任不管就容易引起瀏覽器卡死。所以還是很有必要早點掌握的。(信我,你看完肯定就懂了)
這個按鈕只會在滾動到距離頂部一定位置之後才出現,那麼我們現在抽象出這個功能需求-- 監聽瀏覽器滾動事件,返回當前滾條與頂部的距離
這個需求很簡單,直接寫:
functionshowtop ()
window.onscroll = showtop
但是!在執行的時候會發現存在乙個問題:這個函式的預設執行頻率,太!高!了!。 高到什麼程度呢?以chrome為例,我們可以點選選中乙個頁面的滾動條,然後點選一次鍵盤的【向下方向鍵】,會發現函式執行了8-9次!
然而實際上我們並不需要如此高頻的反饋,畢竟瀏覽器的效能是有限的,不應該浪費在這裡,所以接著討論如何優化這種場景。
基於上述場景,首先提出第一種思路:在第一次觸發事件時,不立即執行函式,而是給出乙個期限值比如200ms,然後:
效果:如果短時間內大量觸發同一事件,只會執行一次函式。
實現:既然前面都提到了計時,那實現的關鍵就在於settimeout
這個函式,由於還需要乙個變數來儲存計時,考慮維護全域性純淨,可以借助閉包來實現:
/** fn [function] 需要防抖的函式
* delay [number] 毫秒,防抖期限值
*/function
debounce(fn,delay)
else
}}
當然 上述**是為了貼合思路,方便理解(這麼貼心不給個贊咩?),寫完會發現其實time = settimeout(fn,delay)
是一定會執行的,所以可以稍微簡化下:
/*****************************簡化後的分割線 *****************************
*/function
debounce(fn,delay)
timer = settimeout(fn,delay) //
簡化寫法}}
//然後是舊**
function
showtop ()
window.onscroll = debounce(showtop,1000) //
為了方便觀察效果我們取個大點的間斷值,實際使用根據需要來配置
此時會發現,必須在停止滾動1秒以後,才會列印出滾動條位置。
到這裡,已經把防抖實現了,現在給出定義:
繼續思考,使用上面的防抖方案來處理問題的結果是:
但是如果產品同學的期望處理方案是:即使使用者不斷拖動滾動條,也能在某個時間間隔之後給出反饋呢?(此處暫且不論哪種方案更合適,既然產品爸爸說話了我們就先考慮怎麼實現)
其實很簡單:我們可以設計一種類似控制閥門一樣定期開放的函式,也就是讓函式執行一次後,在某個時間段內暫時失效,過了這段時間後再重新啟用(類似於技能冷卻時間)。
效果:如果短時間內大量觸發同一事件,那麼在函式執行一次之後,該函式在指定的時間期限內不再工作,直至過了這段時間才重新生效。
functionthrottle(fn,delay)
//工作時間,執行函式並且在間隔期內把狀態位設為無效
valid = false
settimeout(() =>, delay)
}}/*
請注意,節流函式並不止上面這種實現方案,
例如可以完全不借助settimeout,可以把狀態位換成時間戳,然後利用時間戳差值是否大於指定間隔時間來做判定。
也可以直接將settimeout的返回的標記當做判斷條件-判斷當前定時器是否存在,如果存在表示還在冷卻,並且在執行fn之後消除定時器表示啟用,原理都一樣
*///
以下照舊
function
showtop ()
window.onscroll = throttle(showtop,1000)
執行以上**的結果是:
講完了這兩個技巧,下面介紹一下平時開發中常遇到的場景:
頁面resize事件,常見於需要做頁面適配的時候。需要根據最終呈現的頁面情況進行dom渲染(這種情形一般是使用防抖,因為只需要判斷最後一次的變化情況)
js防抖和節流
在進行視窗的resize scroll,輸入框內容校驗等操作時,如果事件處理函式呼叫的頻率無限制,會加重瀏覽器的負擔,導致使用者體驗非常糟糕。此時我們可以採用debounce 防抖 和throttle 節流 的方式來減少呼叫頻率,同時又不影響實際效果。函式防抖 函式防抖 debounce 當持續觸發...
js 防抖和節流
突然被人問到節流和防抖的區別,一臉大寫的懵逼,一直以為他倆是乙個東西。那趕緊學習一下吧。定義 多次觸發事件後,事件處理函式只執行一次,並且是在觸發操作結束時執行。原理 對事件處理函式做延時執行,如果在設定的時間內再次觸發事件函式,清除定時器 cleartimeout 重新計時。適用場景 乙個輸入框連...
js 防抖和節流
很多 都會提供乙個按鈕 用於返回頂部。這個按鈕只會在滾動到距離頂部一定位置的時候才出現 監聽滾動事件,返回當前到頂部的距離 function showtop window.onscroll showtop 但是執行的時候存在乙個問題 函式預設執行頻率太高,按一次鍵盤的下方向鍵,函式就執行了9次!實際...