戲說前端 JavaScript 之『防抖節流』基礎知識
往事不堪回首
猶記在很久之前的某次面試中,和那技術大哥談的正歡呢,冷不防他來了句:談一談防抖和節流吧。
抹了把涼汗,我用顫抖的、不自信的語氣回答道:呃,防抖就是應該是防止抖動的意思,節流大概是節省流量吧……
當時,我的心理活動是這樣的:
當年心理素質是真的差,這個坎沒翻過去,最後的結果就是:
知恥而後勇
以我不服輸的性格,這場子必須找回來!
經過這幾年的勤學苦練,我現在自信簡直爆棚,如果,時光能夠倒流,我相信我可以做到這樣:
今天,我要跟「防抖節流」來做個了斷,以證明現在的我已不是過去的我,用一個成語來形容,那就是——今非昔比!
知己知彼,方能百戰百勝
古老的法則告訴我們:欲要消滅敵人,必須先要了解敵人。
防抖(debounce)
從字面意思來看,防抖就是防止抖動的意思。
舉個例子:比如說你物件要你幫她拍美照, 結果因為你加班太多身體虛,手抖的厲害,拍出來的照片模糊不清,為免受雷霆之怒,你就需要想想辦法。首先,分析一下照片模糊的原因:
- 手抖的厲害(1s 十幾次!!??)
- 導致相機不能完美的捕捉畫面
- 所以照片模糊。
看來,「手抖」才是罪魁禍首啊,那想個辦法解決手抖的問題就好了:找一個支架,讓它代替手來支撐相機,這樣就不「抖」了!
這操作,讓我不得不對你豎起大拇指:
想想看上面這個例子本質上是解決了什麼問題?
我覺得應該是解決了「抖動頻率」的問題——手拿著,一秒會抖好多次;可支架撐著,好長時間都未必會抖一次。可謂是「人不如架」啊!
支架起的就是防抖的作用。
回到我們今天的正題上,來看一下防抖的常規解釋:當函式被連續呼叫時,該函式並不執行,只有當其全部停止呼叫超過一定時間後才執行1次。
節流(throttle)
現在回頭看看我當年的回答,還是摸到了一點門檻(手動緩解尷尬,嘿嘿)。
再來個例子:家裡的水龍頭,即使你開的再大,它在單位時間裡能流出的水就那麼多,因為水龍頭的規格限制了它單位時間裡的流量。
水龍頭起到的就是節流的作用。
節流的常規解釋:規定一個單位時間,在這個單位時間內,只能有一次觸發事件的回撥函式執行,如果在同一個單位時間內某事件被觸發多次,只有一次能生效。
常用場景
防抖節流一般用於以下場景:
- 瀏覽器視窗的縮放,頁面的滑動觸發的
resize
scroll
- 滑鼠事件
onmousemove
,onmousedown
,onmouseup
- 輸入框錄入觸發的
keyup
,keydown
……
原理
防抖是維護一個計時器,規定在 delay 時間後觸發函式,但是在 delay 時間內再次觸發的話,都會清除當前的 timer 然後重新設定超時呼叫,即重新計時。這樣一來,只有最後一次操作能被觸發。
節流是通過判斷是否到達一定時間來觸發函式,若沒到規定時間則使用計時器延後,而下一次事件則會重新設定計時器。
區別
函式防抖是某一段時間內只執行一次,而函式節流是間隔時間執行,不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函式。
總結
今天就先來了解一下「防抖」和「節流」的基礎知識,詳細程式碼實現待後續。
~
- ~
- 未完待續
學習有趣的知識,結識有趣的朋友,塑造有趣的靈魂!
大家好!我是〖程式設計三昧〗的作者 隱逸王,我的公眾號是『程式設計三昧』,歡迎關注,希望大家多多指教!
知識與技能並重,內力和外功兼修,理論和實踐兩手都要抓、兩手都要硬!