使用場景
有些時候,部分函式會高頻觸發,比如:
functionshowtop ()
window.onscroll = showtop
這個函式的觸發頻率非常的高,然而實際上我們並不需要如此高頻的反饋,畢竟瀏覽器的效能是有限的,不應該浪費在這裡,優化這種場景的做法就是防抖。
其他使用場景:
頁面resize事件,常見於需要做頁面適配的時候。需要根據最終呈現的頁面情況進行dom渲染(這種情形一般是使用防抖,因為只需要判斷最後一次的變化情況)
防抖(debounce)
基於上述場景,首先提出第一種思路:在第一次觸發事件時,不立即執行函式,而是給出乙個期限值比如200ms,然後:
效果:如果短時間內大量觸發同一事件,只會執行一次函式。
實現:既然前面都提到了計時,那實現的關鍵就在於settimeout
這個函式,由於還需要乙個變數來儲存計時,考慮維護全域性純淨,可以借助閉包來實現:
/** fn [function] 需要防抖的函式
* delay [number] 毫秒,防抖期限值
*/function
debounce(fn,delay)
else
}}
將**簡化
/*****************************簡化後的分割線 *****************************
*/function
debounce(fn,delay)
timer = settimeout(fn,delay) //
簡化寫法}}
//然後是舊**
function
showtop ()
window.onscroll = debounce(showtop,1000) //
為了方便觀察效果我們取個大點的間斷值,實際使用根據需要來配置
到這裡,已經把防抖實現了,現在給出定義:
節流(throttle)
使用上面的防抖方案來處理問題的結果是:
但是如果產品同學的期望處理方案是:即使使用者不斷拖動滾動條,也能在某個時間間隔之後給出反饋呢?(此處暫且不論哪種方案更合適,既然產品爸爸說話了我們就先考慮怎麼實現)
我們可以設計一種類似控制閥門一樣定期開放的函式,也就是讓函式執行一次後,在某個時間段內暫時失效,過了這段時間後再重新啟用(類似於技能冷卻時間)
效果:如果短時間內大量觸發同一事件,那麼在函式執行一次之後,該函式在指定的時間期限內不再工作,直至過了這段時間才重新生效。
functionthrottle(fn,delay)
//工作時間,執行函式並且在間隔期內把狀態位設為無效
valid = false
settimeout(() =>, delay)
}}/*
請注意,節流函式並不止上面這種實現方案,
例如可以完全不借助settimeout,可以把狀態位換成時間戳,然後利用時間戳差值是否大於指定間隔時間來做判定。
也可以直接將settimeout的返回的標記當做判斷條件-判斷當前定時器是否存在,如果存在表示還在冷卻,並且在執行fn之後消除定時器表示啟用,原理都一樣
*///
以下照舊
function
showtop ()
window.onscroll = throttle(showtop,1000)
執行以上**的結果是:
截流 和 防抖
截流防抖函式經常用在頻繁按鈕操作,頁面滾動觸發,滑鼠拖拽,輸入查詢等功能中。是為了在頻繁操作中為了減少效能損耗的小技巧,這兩個概念常用但是又容易混淆,下面簡單的分析下防抖與截流的異同之處 意味著防止抖動出現的誤操作,也就是防止像抖動一樣的頻繁操作。所以在防抖函式裡會有個時間限制,當函式在一次執行之後...
js 防抖 截流
突發奇想,在觸發事件的時候,一些會頻繁觸發的事件會不會造成資源的浪費或者大量的計算造成頁面卡頓,比如onresize,onscroll,onmousemove等事件。然後就引出了乙個新知識點 防抖 截流。防抖 是指在事件觸發結束後延時一段時間再去執行 如果在延時期間再次觸發該事件,則重新計算延時時間...
防抖與截流總結
防抖 是指在事件觸發結束後延時一段時間再去執行 如果在延時期間再次觸發該事件,則重新計算延時時間 第乙個引數為事件觸發後需要執行的方法,第二個引數為延時時間function debounce method,delay timer settimeout function delay let fun d...