我們在web項目中經常會需要用到 圖片懶加載 ,設置中我們需要監聽scroll
滾動條滾動事件
。這種事件響應得十分頻繁,當我們監聽器的回調函數越復雜,對性能影響就會越嚴重。為此我們利用定時器
,使事件回調函數在監聽中按照固定的事件間隔觸發,而不是每像素移動都觸發。
跟普通的事件監聽設置基本一樣,我們只要對回調函數體進行一次封裝。
這里我封裝了一個函數,參考了小程序API的設計模式,我們只傳遞一個map。
lazyEvent.throttle({
dom: window, // 綁定事件監聽的dom
eventName: 'scroll', // 監聽什么事件
delay: 100, // 回調函數觸發的時間間隔
event: res => { // 回調函數執行了什么
console.log(1)
}
})
接下來我們只需要看懂下文標記的10行左右代碼即可學會函數節流
export class lazyEvent {
constructor() {}
/* 函數節流 */
static throttle(map){
/* 取map傳進來的值 */
let DOM = map.dom
let eventName = map.eventName
let event = map.event
let delay = map.delay ? map.delay : 100
/* ----------------這里是重點↓ ------------------*/
let timer = null // 外部定義timer變量,用來存定時器ID
let newEvent = function () { // 聲明一個新函數,用來包裹我們目標函數體
if(timer){ // 如果有定時器就不繼續執行下面的代碼
return
}else{ // 如果沒有定時器就執行目標函數體,然后設置一個定時器
event() // 目標函數體
timer = setTimeout(function () { // 這個定時器一個時間間隔后會銷毀自身
clearTimeout(timer)
timer = null
},delay)
}
}
/* -----------------這里是重點↑ --------------------*/
DOM.addEventListener(eventName, newEvent)
}
}
1.首先呢,這個 newEvent就是一層皮
,里面包了我們 真正要執行的事件響應
,以及我們本次要添加的一個定時器
。
2.定時器函數的返回值是這個 定時器的ID
我們需要在 '皮' 外 存一下。
3.這個定時器的回調函數就是銷毀它自身,并且清空我們存儲的ID,所以我們可以通過ID判斷當前有沒有定時器。
4.我們進入 '皮' 里有一個判斷,現在有定時器嗎? 如果有我們就立即結束本次響應。如果沒有我們就執行我們的目標 -- 響應事件
,然后沒有我們就再做一個定時器唄。
以上就是函數節流的主要內容,希望大家能夠學會。ps.類似的事件還有resize,mousemove這種。