函數防抖主要就是防止頻繁觸發事件就會頻繁觸發回調,回調要是操作dom或者其他耗時工作,浏覽器受不了。
函數防抖:
好比電梯需要上人,來一個人,就要等幾秒再走,再來個人又要多等一樣的時間,再來一樣。
在網上看到也有個比較恰當的比喻,好比網絡遊戲法師施法,點選之後正在讀進度條,你又點了一次,那隻能從頭再讀,每次點都得從頭讀。
實作代碼如下:
function debounce (func, wait) {
var lastCallTime
var lastThis
var lastArgs
var timerId
function startTimer (timerExpired, wait) {
return setTimeout(timerExpired, wait)
}
function remainingWait(time) {
const timeSinceLastCall = time - lastCallTime
const timeWaiting = wait - timeSinceLastCall
return timeWaiting
}
function shoudInvoking (time) {
return lastCallTime !== undefined && (time - lastCallTime >= wait)
}
function timerExpired () {
const time = Date.now()
// 一個勁猛點的話這個if裡永遠滿足不了條件,隻有你停下來等一會,就會有結果了
if (shoudInvoking(time)) {
return invokeFunc()
}
timerId = startTimer(timerExpired, remainingWait(time))
}
function invokeFunc () {
timerId = undefined
const args = lastArgs
const thisArg = lastThis
let result = func.apply(thisArg, args)
lastArgs = lastThis = undefined
return result
}
function debounced (...args) {
let time = Date.now()
lastThis = this
lastArgs = args
lastCallTime = time
// invokeFunc函數沒結果之前,再點選多少次下邊這個函數都不執行了.點選隻會更改lastCallTime
// 更改了lastCallTime,
if (timerId === undefined) {
timerId = startTimer(timerExpired, wait)
}
}
return debounced
}
window.addEventListener('click', debounce(function (event) {
var p = document.createElement('p')
p.innerHTML = 'trigger'
document.body.appendChild(p)
return 'aaaa'
}, 500))
可以使用lodash 中的 debounce函數。省去自己寫的麻煩。但是原理了解一下,沒壞處。