防抖(debounce)-性能優化方式之一
監聽一個輸入框,文字變化後觸發change事件,直接用Keyup事件,則會頻繁觸發change事件;防抖:使用者輸入結束或者暫停時(觸發間隔操過設定時間時才進行指定操作),才觸發change事件
說在前面:
1)aplly用法詳解
2)keyup事件
代碼實作:
1:未封裝版本
const inputDom = document.getElementById('input')
let timer
inputDom.addEventListener('keyup', () => {
if(timer) {
claerTimeout(timer)
}
timer = setTimeout(() => {
// 模拟觸發change事件
console.log(inputDom.value)
// 清空計時器
timer = null
}, 500)
})
比如輸入連續輸入123,觸發了三次keyup事件;輸入1時,timer為空,便給timer設定了個0.5s的計時器,語氣是到了時間再針對1觸發change事件,但随後立即又輸入了2,這時timer有值,便清空了對1的計時器,重新設定了0.5s關于2可以觸發change事件的計時器,最後又輸入3,同理最後隻剩下關于3的可觸發change事件的計時器;等到0.5s後發現暫無輸入,便觸發了change事件;減少了觸發change事件的次數:觸發間隔操過設定時間時才進行指定操作
2)封裝版本
function debounce(fn, delay = 500) {
// 是閉包中的
let timer
// input事件調用的函數,相當于obj調用函數 this指向Input
return function() {
// 這個if 判斷不做也沒關系,可直接清空,隻有第一次timer非空
if(timer) {
claerTimeout(timer)
}
// 此時的箭頭函數的this 和 arguments 都是從外部函數繼承而來
// r如果用普通函數就要用詞法作用域 var thsta = this var arg = arguments
timer = setTimeOut(() =>{
// 使得傳入的回調函數的this 指向Input這個元素對象
// arguments是該事件的詳情,可以獲得該函數被調用時的所有參數,是一個event 對象(所有Dom事件都會傳event對象進入)
// 直接使用 fn() 問題也不大
fn.apply(this,arguments)
timer = null
},delay)
}
}
// 直接使用
input.addEventListener('keyup', debounce(() => {
// 可直接使用this.value獲得輸入框的值; arguments可用于擷取具體觸發事件的資訊
console.log(input.value)
}), 600)