极简实现系列 是用最简单的代码实现一些常见的方法,目的是为了帮助理解原理,所以并没有考虑太多限制条件
防抖函数在日常中还是经常用到的。实现的原理也非常简单,就是利用setTimeout给需要防抖的方法一个延时执行,每次调用的时候重置setTimeout
知道原理后很要很容易的写出一个极简版
let timer = null
function debounce(fn, delay) { // fn: 需要防抖的函数,delay:延迟的时间
clearTimeout(timer)
timer = setTimeout(fn, delay)
}
我们来测试一下,写一个input输入框和一个测试函数,input每次输入的时候都打印一个1
<input type="text" id="input">
<script>
function test() {
console.log(1)
}
document.querySelector('#input').addEventListener('input', () => {
test()
})
</script>
加上刚才写的防抖函数试试:
<input type="text" id="input">
<script>
let timer = null
function debounce(fn, delay) {
clearTimeout(timer)
timer = setTimeout(fn, delay)
}
function test() {
console.log(1)
}
document.querySelector('#input').addEventListener('input', () => {
debounce(test, 1000)
})
</script>
会在停止输入后过一秒才打印1
看来极简版的防抖函数成功了~~
当然,这样是没什么问题,但是在实际中使用的话还可以再优化下,比如timer这个变量我们定义成全局的,这样有可能会造成污染,还有如果test函数有参数的话,极简版是没办法做到传参数的。我们再来稍微优化一下
优化版:
function debounce(fn, delay) {
let that = this // 获取上下文
let timer = null // 利用闭包,避免污染
return function() {
let args = arguments // 获取当前参数
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(that, args)
}, delay)
}
}
function test(e) {
console.log(e)
}
let debounceTest = debounce(test, 1000) // debounce返回一个函数
document.querySelector('#input').addEventListener('input', (e) => {
// test()
debounceTest(e.target.value)
})
完事~