為什麼要有節流和防抖
在前端開發中有一部分的使用者行為會頻繁的觸發事件執行,比如視窗的resize、scroll,提交表單等。而事件處理函式呼叫的頻率無限制,很可能導致介面卡頓,甚至瀏覽器的崩潰。函式節流和函式防抖就是為了解決類似需求而生的
函式防抖
在事件被觸發n秒後再執行**,如果在這n秒內又被觸發,則重新計時。也就是說,短時間內無論事件觸發多少次,總是只會執行最後一次事件的**方法
看乙個例子
執行結果
先來說一下我的輸入:1 》2 》3 》4 》5 》6 》7 》8 》9,輸入9次,列印了9次,也就是說輸入一次列印一次;
可以看到,我們只要按下鍵盤,就會觸發這次ajax請求。不僅從資源上來說是很浪費的行為,而且實際應用中,使用者也是輸出完整的字元後,才會請求;
利用防抖
將請求函式 ajax 作為 settimeout 的**函式,設定 settimeout 的時間為wait。需要乙個變數 timeout 來儲存當前所處的計時階段,如果距離上次事件發生的 wait 時間段內再次發生該事件,那麼把 timeout 清楚,即把上次的 settimeout 事件清除,並重新計時;如果 wait 期間內沒有再次觸發相同事件,那麼執行 fn 方法,即執行 ajax 方法。
執行結果
還是
先說下我是怎麼輸入這9個數字的:先輸入123,停了1秒多(列印出123),再次輸入456,又停了一秒多(列印出123456),輸入789(1秒後,列印出123456789);
當持續觸發 keyup 事件時,ajax 請求函式只在keyup事件停止1000毫秒之後才會呼叫一次,也就是說,在持續觸發keyup事件的過程中,請求函式ajax一直沒有執行;
可以看到,我們加入了防抖以後,當你在頻繁的輸入時,並不會傳送請求,只有你在指定時間間隔內沒有輸入時,才會執行函式。如果停止輸入但是在指定時間間隔內又輸入,會重新觸發計時。
函式節流
引用1:
當持續觸發事件時,保證一定時間段內只呼叫一次事件處理函式。也就是說,預定乙個函式只有在大於等於執行週期時才執行,週期內呼叫不執行;
引用2:規定在乙個單位時間內,只能觸發一次函式。如果這個單位時間內觸發多次函式,只有一次生效;
舉個例子
當事件觸發的時候,我們設定乙個定時器,再次觸發事件的時候,如果定時器存在,就不執行,直到 wait 時間後,定時器執行函式,並且清空定時器,這樣就可以設定下個定時器;
當第一次觸發事件時,不會立即執行函式,而是延遲 wait 秒後才執行。而後再怎麼頻繁觸發事件,也都是每 wait 時間才執行一次。當最後一次停止觸發後,由於定時器的 wait 的延遲,可能還會執行一次函式;
執行結果
我的輸入:在1秒之內輸入 123,但是只列印出了 1,說明在 1 秒內觸發多次事件,只會執行一次。
適用場景
debounce(防抖)
1、
search搜尋聯想,使用者在不斷輸入值時,用防抖來節約請求資源
2、window觸發 resize 的時候,不斷地調整瀏覽器視窗大小會不斷觸發這個事件,用防抖來讓其只觸發一次
throttle(節流)
1、滑鼠不斷點選提交,一段時間內只讓一次點選生效
2、監聽滾動事件,比如是否滑到底部自動載入更多
參考部落格:
js防抖和節流
在進行視窗的resize scroll,輸入框內容校驗等操作時,如果事件處理函式呼叫的頻率無限制,會加重瀏覽器的負擔,導致使用者體驗非常糟糕。此時我們可以採用debounce 防抖 和throttle 節流 的方式來減少呼叫頻率,同時又不影響實際效果。函式防抖 函式防抖 debounce 當持續觸發...
js 防抖和節流
突然被人問到節流和防抖的區別,一臉大寫的懵逼,一直以為他倆是乙個東西。那趕緊學習一下吧。定義 多次觸發事件後,事件處理函式只執行一次,並且是在觸發操作結束時執行。原理 對事件處理函式做延時執行,如果在設定的時間內再次觸發事件函式,清除定時器 cleartimeout 重新計時。適用場景 乙個輸入框連...
js 防抖和節流
很多 都會提供乙個按鈕 用於返回頂部。這個按鈕只會在滾動到距離頂部一定位置的時候才出現 監聽滾動事件,返回當前到頂部的距離 function showtop window.onscroll showtop 但是執行的時候存在乙個問題 函式預設執行頻率太高,按一次鍵盤的下方向鍵,函式就執行了9次!實際...