防抖(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)