什么是防抖
防抖我的个人理解就是如果你触发一个事件在一个指定时间内没有再次触发那么就会执行这个事件对应的操作,否则就会关闭上次的事件只执行这次的.举例就是回城动画,回城需要时间,在这个时间走完后才能回城.如果你动了一下那么下次回城就要重新计算时间.
简单案例
我们从上面了解到几个关键字-----一个事件~指定时间~只执行一次
<style>
* {
margin: 0;
padding: 0;
}
h1 {
margin-top: 200px;
text-align: center;
}
div {
margin: 100px auto;
padding-left: 20px;
border-radius: 30px;
width: 200px;
height: 30px;
border: 1px solid black;
}
input {
border: 0;
outline: none;
height: 100%;
/* background-color: red; */
}
</style>
//声明一个h1标签和input框
<h1></h1>
<div>
<input type="text" placeholder="请输入你要查询的内容">
</div>
<script>
let input = document.querySelector("input");
let h1 = document.querySelector("h1");
let timer = null
//监听输入事件
input.addEventListener("input", function (e) {
//清除上次执行的函数,相当于打断回城
clearTimeout(timer);
let value = e.target.value
timer = setTimeout(() => {
h1.innerHTML = value
}, 500)
})
</script>
上面的案例是一个输入案例,500毫秒的指定时间内输入触发给h1标签赋值的函数,但是这个函数每次都会清除上次的setTimeout,确保只执行一次.
封装版本
let debouncedFn = debounced(v => {
console.log(122);
h1.innerHTML = v
}, 500); //这里返回的是谁呢?是debounced返回的那个防抖函数
input.addEventListener("input", (e) => {
debouncedFn(e.target.value)//这里的传参会被debounced返回的函数接收
})
// 函数版
function debounced(fn, delay) {
let timer = null
return function (v) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn(v)
}, delay)
}
}
要注意不是直接去调用封装的函数,而是先把封装函数内返回的函数取出来.然后去调用这个返回的函数.这样才会形成闭包,否则就是在重复执行这个函数没有意义.还有要注意函数不能直接传入就写,要给个回调函数包裹,毕竟这是个过程函数(执行里面的逻辑没有返回值)