防抖节流经常在面试中经常被问到,它也确实是经常被我们解决频繁触发DOM事件的两种解决方案。那今天就来聊一聊防抖与节流吧。
什么是防抖
就比如滚轮的滚动事件,或者是 input表单,当我们获取输入框的值时我们可能需要的时用户最后输入的内容,而不是输入一个字母就触发一次,这个时候我们就需要使用防抖函数。
概念
防抖就是一定时间内只执行最后一次任务;
封装防抖函数 debounce
在一定时间内事件被频繁的触发,只执行最后一次事件
接下来我们来看一下代码。
首先在页面中创建一个文本框
<input type="text" />
假如我们不使用防抖函数获取输入框的value值效果
let inValue = document.querySelector("input");
inValue.oninput = function(){
//这样会让事件不停的触发,影响性能
console.log(this.value);
}
我们可能需要的只是最后的一个结果,但是你在输入内容时就会不停的触发事件,需要执行好多次,这样大大影响了效率。 所以我们需要进行接下来的防抖操作。
封装防抖函数
<script>
//一般用在滚动条,input事件中
let inValue = document.querySelector("input");
//封装防抖函数(利用定时器,闭包。在一段时间内不停的被触发,前面的事件会被清除,只执行最后一次触发的事件,在一定时间内只触发一次)
inValue.oninput = debounce(function () {
// 此函数执行的是业务逻辑
console.log(this.value);
}, 500);
function debounce(fn, delay) {
//此时timer不是全局变量,不会被释放.
let timer = null;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fn.call(this);
}, delay);
};
}
</script>
实现的效果如下:
这样的话拿到的是最终的一次结果,在每次输入时下一次事件都会将上次的事件清空,以至于只执行了一定时间内的最后一次事件。
节流
概念
节流就是一定时间内只执行一次任务,控制执行次数
控制执行次数:fn 要执行时,等待 delay 时间完了之后再执行 fn
我们以滚轮事件为例,
不使用节流时的效果,只要你操作滚轮事件就会不停的触发,和上面防抖的效果差不多。
window.onscroll = function(){
console.log(111);
}
使用节流函数时的效果一段事件内只触发一次、
<script>
//节流:控制执行次数
window.onscroll = throttle(function () {
console.log(111);
}, 1000);
//封装节流函数
function throttle(fn, delay) {
let timer = null;
return function () {
if (!timer) {
//此时你不停的滑动滚轮,也是500毫秒输出一次内容。
timer = setTimeout(() => {
fn.call(this);
timer = null;
}, 1000);
}
};
}
</script>