js 的 節流 和 防抖
阿新 • • 發佈:2021-12-13
目錄
節流 和 防抖 簡介
在使用者進行瀏覽器頁面的操作時,可能會發生一段時間內(如1s內),連續、頻繁點選某個操作按鈕,導致頻繁操作dom或者向後臺發出請求,可能會造成頁面卡頓或者伺服器擁堵。針對此種情況,可以使用js的 節流 和 防抖 來解決。
節流 和 防抖 這兩種方式的實現原理都是利用 setTimeOut 定時器來實現的,將使用者的操作延遲執行。
節流 和 防抖 區別
節流,採用“間隔一段時間後執行”,即 第一次觸發時,先建立一個定時器,在一定時間後再執行觸發事件,同時將定時器置為空,若在一定時間內(比如1s內)再次觸發,則會判斷定時器是否存在,如果存在,則不再建立新的定時器(後續的觸發事件不會執行);
防抖,採用“延遲執行觸發,並清除上一次的定時器”,即 第一次觸發時,先建立一個定時器,在一定時間後再執行觸發事件,若在一定時間內(比如1s內)再次觸發,則會清除之前的定時器,重新新建一個定時器;這樣會有一個缺點,就是 若在一段時間內不停地觸發事件,那麼該事件的執行會被無限期地延後。
應用場景
-
節流
- 防止表單提交時重複多次觸發事件;
-
防抖
-
視窗resize需計算視窗的大小時,需等使用者的拖拽事件完成後執行計算方法;
-
input 輸入框的實時查詢事件,在使用者不斷輸入的過程中不觸發查詢,等使用者輸入完停止一段時間後再觸發
-
程式碼實現
- 節流
function clickFn() { console.log('clickFn'); } // 節流,一段時間內只能觸發一次函式,若觸發多次,則只有一次生效(相當於執行這段時間內第一次點選的事件) function dealFn(func, time) { let timer = null; return function() { let that = this; if(!timer) { timer = setTimeout(() => { func.call(that); timer = null; }, time) } } } let submitClick = dealFn(clickFn, 1000); submitClick(); submitClick(); setTimeout(()=> { console.log("..."); submitClick(); }, 1000);
- 防抖
function clickFn() { console.log('clickFn'); } // 防抖,一段時間內觸發多次函式時,每次觸發都延遲函式呼叫,並在下一次觸發時清除之前的定時器(相當於執行這段時間內最後一次點選的事件) // 每次觸發事件時設定一個延遲呼叫方法,並且取消之前的延時呼叫方法 // 缺點:如果事件在規定的時間間隔內被不斷的觸發,則呼叫方法會被不斷的延遲 function dealFn(func, time) { let timer = null; return function() { let that = this; clearTimeout(timer); timer = setTimeout(() => { func.call(that); }, time) } } let submitClick = dealFn(clickFn, 1000); submitClick(); submitClick(); setTimeout(()=> { console.log("..."); submitClick(); }, 1000);
擴充套件知識點
1、call 和 apply
詳見 javaScript---bind、call、apply
2、閉包
之所以在後續的方法呼叫(submitClick()
)時,能刪除之前呼叫時定義的 timer,是因為 js 的閉包,使得對於這些呼叫來說,timer 成為了一個“全域性變數”。