防抖(debounce):當持續觸發事件時,保證只執行最后一次事件處理函式
在給DOM系結事件時,有些事件我們是無法控制觸發頻率的, 如滑鼠移動事件onmousemove, 滾動滾動條事件onscroll,視窗大小改變事件onresize,瞬間的操作都會導致這些事件會被高頻觸發, 如果事件的回呼函式較為復雜,就會導致回應跟不上觸發,出現頁面卡頓,假死現象, 在實時檢查輸入時,如果我們系結onkeyup事件發請求去服務端檢查,用戶輸入程序中,事件的觸發頻率也會很高,會導致大量的請求發出,回應速度會大大跟不上觸發,
如何實作防抖呢?
我們拿滾動事件舉例子,用戶的滾動會頻繁觸發滾動事件,很容易造成頁面卡死,那么我們可以封裝如下一個函式,每次想呼叫函式的時候,設定一個定時器讓函式延遲執行,當連續觸發的時候,前面每次定時器都會清除掉,都會停掉前面的定時器所以函式并不會運行,只會執行最后一次,
// 防抖
function debounce(fn) {
let timeout = null; // 創建一個標記用來存放定時器的回傳值
return function () {
clearTimeout(timeout); // 每當用戶輸入的時候把前一個 setTimeout clear 掉
timeout = setTimeout(() => { // 然后又創建一個新的 setTimeout, 這樣就能保證輸入字符后的 interval 間隔內如果還有字符輸入的話,就不會執行 fn 函式
fn()
}, 500);
};
}
function sayHi() {
console.log('防抖成功');
}
let box = document.getElementById('box')
box.addEventListener('click', debounce(sayHi))
節流(throttle)::當持續觸發事件時,保證一定時間段內只呼叫一次事件處理函式
節流通俗解釋就比如我們水龍頭放水,閥門一打開,水嘩嘩的往下流,秉著勤儉節約的優良傳統美德,我們要把水龍頭關小點,最好是如我們心意按照一定規律在某個時間間隔內一滴一滴的往下滴,
如何實作節流?
當用戶連續操作的時候,我們設定一個定時器,一段時間后執行函式,并且執行完把標記改為true,所以在函式沒有執行完之前一直是false,可能有的同學認為連續操作那么函式連續運行,那么canRun這個標記不一直是true嗎,并不是,注意這里是一個閉包結構,真正每次呼叫的其實是throttle里面return的函式并不是每次都呼叫throttle,所以canRun只是提供初始值,并不會每次都重新賦值為true,所以用戶連續操作的時候,比如用戶一秒鐘連續操作了十次,但是對于我們這個代碼來說,只可能每500毫秒執行一次,因為只有500ms之后canRun才為true,才能開啟下一個定時器,所以哪怕用戶一秒鐘之內連續點了十次,其實也只是能執行兩次,這就符合節流的本意,
function throttle(fn) {
let canRun = true; // 通過閉包保存一個標記
return function () {
if (!canRun) return; // 在函式開頭判斷標記是否為true,不為true則return
canRun = false; // 立即設定為false
setTimeout(() => { // 將外部傳入的函式的執行放在setTimeout中
fn()
// 最后在setTimeout執行完畢后再把標記設定為true(關鍵)表示可以執行下一次回圈了,當定時器沒有執行的時候標記永遠是false,在開頭被return掉
canRun = true;
}, 500);
};
}
function sayHi(e) {
console.log('節流');
}
window.addEventListener('resize', throttle(sayHi));
總結:防抖動和節流本質是不一樣的,防抖動是將多次執行變為最后一次執行,節流是將多次執行變成每隔一段時間執行,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/266687.html
標籤:其他
