应用
- 防抖与节流函数,可以控制事件被触发的频率,主要应用于以下场景
- 输入框,需要监测键盘按下抬起事件 – onkeyup、onkeydown
- 浏览器窗口的尺寸变化事件 – onresize
- 溢出滚动事件 – onscroll
- 按钮点击事件,防止重复提交 – onclick
区别
防抖(debounce)
- 函数在触发后,规定在时间范围内只执行一次。如果再次触发了函数,则重新计时,取消之前的调用。即无论被触发多少次,只取最后一次。
节流(throttle)
- 函数在时间范围内,只执行一次。在此时间范围内,判断是否有过调用,如果已经调用过,则禁止再触次发执行函数。
实现
防抖(debounce)
<template>
<div class="hello">
<input type="text" v-model="myText" @keyup="keyupFunc" />
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
myText: "",
timmer: null,
};
},
methods: {
debounce(func, delay) {
return (() => {
if (this.timmer) {
console.log("%c清理定时器的操作~", "color: blue;");
clearTimeout(this.timmer);
}
this.timmer = setTimeout(func, delay);
})();
},
keyupFunc() {
let time = new Date().getTime();
console.log(
"%c不加入防抖-触发结果:" + this.myText + ",时间戳:" + time,
"color: red;"
);
this.debounce(() => {
console.log(
"%c加入防抖-触发结果:" + this.myText + ",时间戳:" + time,
"color: green;"
);
this.timmer = null;
}, 2000);
},
},
};
</script>
![在这里插入图片描述](https://img-blog.csdnimg.cn/febfaa8a3ddb46b18b7dbe7d57655f3e.png)
- 输入框中频繁连续输入数字 1,不加防抖的 console 每次都会被执行,并且从第二次开始,有清理定时器的操作。
- 在 2 秒内不再操作时,打印绿色字体,此时才被认为事件触发。
- 实际应用
- 监听 input 的键盘抬起事件(如上例),在抬起 2 秒后未再次触发函数,则认定用户不再输入,此时做输入内容的校验、远程搜索等功能。
- 浏览器大小的变化,onresize 事件,在尺寸变化被触发后,2 秒内不再被触发,则认为用户不再拖动尺寸大小,此时做尺寸适配、重新加载数据等功能。
节流(throttle)
<template>
<div class="helloBox" @scroll="scrollFunc" ref="helloBox">
<div class="helloLong"></div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
myText: "",
timmer: null,
};
},
methods: {
throttle(func, delay) {
return (() => {
if (this.timmer) {
console.log(
"%c已经执行过了,停止方法",
"color: blue;",
this.timmer
);
return;
} else {
this.timmer = setTimeout(func, delay);
}
})();
},
scrollFunc() {
let height = this.$refs.helloBox.scrollTop;
let time = new Date().getTime();
console.log(
"%c不加入节流-触发结果:卷曲出去的距离:" +
height +
",时间戳:" +
time,
"color: red;"
);
this.throttle(() => {
console.log(
"%c加入节流-触发结果:卷曲出去的距离:" +
height +
",时间戳:" +
time,
"color: green;"
);
this.timmer = null;
}, 200);
},
},
};
</script>
<style scoped>
.helloBox {
height: 100%;
overflow-y: scroll;
}
.helloLong {
height: 500%;
}
</style>
![在这里插入图片描述](https://img-blog.csdnimg.cn/7c638019a2eb4f1ba9197dc51df6b865.png)
- 向下滚动时,每隔一段时间,触发一次节流事件。
- 除了定时器,节流函数还可用时间戳控制事件的触发。
- 实际应用
- 需要监听页面滚动事件时(如上例),防止监听事件频繁触发。
- 表单提交事件,防止用户重复提交,可规定在一定时间内,提交时间只能被触发一次。