防抖这里两个词可能对一些初入JavaScript的同学比较陌生,那这篇文章主要是针对这些同学们的,浅谈一下防抖
1.”防抖”是什么
首先,先去解释一下什么叫做防抖, 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。纯理论是比较抽象的,还是用代码来的实在。
假设: 我有一个标签,并想获得输入时的值,代码是这样的:
<body>
<input type="text">
<script>
let input = document.querySelector("input");
input.addEventListener('input',function(){
console.log(this.value);
})
</script>
</body>
我们输入一些值之后,得出的效果是这样的:
我们只是输入了 “前端”两个字,控制台中就打印了很多次,事件就执行了很多次。假设我们每一次输入都是和后台进行一次数据交互的话,那执行这么多次事件就会太影响性能了。
那么我们考虑的就是怎样减少与后台数据库请求的次数,那么防抖就应用而生了。
也就是说 用户触发时间过于频繁,只要最后一次请求的操作就叫做防抖
2.怎么做
用户虽然触发了多次,但是我们想要的只是用户操作的最后一次,那么应该怎样去实现呢?
其实可以把问题简单化,我们只要隔一个固定的事件去获取一次用户输入的值,那么事件触发的次数就会减少,这个就是防抖的实现。
现在用代码去实现:
<body>
<input type="text">
<script>
let input = document.querySelector("input");
let time = null;//time用来控制事件的触发
input.addEventListener('input',function(){
//防抖语句
if(time !== null){
clearTimeout(time);
}
time = setTimeout(() => {
console.log(this.value);//业务实现语句
//这里的this指向的是input
},500)
})
</script>
</body>
用 time 来控制事件的触发,然后建立一个延时器,用固定事件500ms来控制事件的触发,输出this.value ,那么之前,需要进行一个判断,判断time是不是有值,如果有值就去清掉time,然后下面的代码又重新赋值给time`。
3.优化:
防抖实现了,但是新的问题又来了,我们定义了一个全局变量time,而且防抖的代码和业务逻辑混到了一起了,那么这个代码就非常不利于维护。那么我们应该怎么解决这个问题呢?这时可以用闭包来封装一个防抖的函数
<body>
<input type="text">
<script>
let input = document.querySelector("input");
//input事件触发的时候,执行的是debounce返回的function,这个function里面有防抖和真正的业务逻辑
input.addEventListener('input', debounce(function () {
/*
用debounce函数去约束input这个事件,实际执行的函数是function函数,防抖的延迟是500ms
*/
console.log(this.value);//业务代码
}, 500));
//需要让debounce的返回值是一个函数
/*
fn : 回调函数 传进来的是正真的业务逻辑
delay : 延时时间
*/
function debounce(fn, delay) {
let time = null;//time用来控制事件的触发
return function () {
if (time !== null) {
clearTimeout(time);
}
time = setTimeout(() => {
fn.call(this);
//利用call(),让this的指针从指向window 转成指向input
}, delay)
}
}
</script>
</body>
这样,一个真正工程化的防抖就完成了
One thought on “JS中的防抖应用一看就会”