节流与防抖
input, keyup,mousemove,resize,scroll 等短时内频繁触发的事件,我们并不需要如此频繁的执行,就可以使用到节流和防抖了
防抖debounce
特定时间内,多次触发只执行最后一次
vue中做防抖处理
// 2s内出触多次,只会执行最后一次
<input type="text" @input="deboundeInput" />
dealInput() {
console.log(666);
},
deboundeInput() {
if (this.timer) clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.dealInput();
}, 500);
},
},
使用场景
搜索框的联想
防抖的实现
1.定时器防抖
将真正要执行的函数代码放到一个定时器中,每次添加定时器前都要清除前面的定时器,这样前面的定时器就被清除,不会执行了;然后在重新添加一个定时器,这样就保证了最后只剩一个定时器,从而实现了一定时间内,多次触发的话,只会执行最后一次了
<input type="text" class="input" />
<script>
var dom = document.querySelector(".input");
dom.addEventListener("input", debounce);
var timer = null;
function debounce(fn) { // 频繁触发的函数
if (timer) clearTimeout(timer); // 如果前面的定时器还没执行,就清除了,不会执行了
timer = setTimeout(() => { // 重新添加一个定时器
console.log(666); // 短时内频繁触发,但是一定时间内,只会执行最后一次的函数
}, 1000);
}
</script>
2.借助lodash实现防抖
// vue中使用lodash防抖,先 npm i lodash --save
<input type="text" @input="inputDebounce" />
<script>
import { debounce } from "lodash";
export default {
data() {
return {
inputDebounce: () => {},
};
},
mounted() {
this.inputDebounce = debounce(this.fndealInput, 1000);
},
methods: {
dealInput() {
console.log(456);
},
},
};
</script>
3.时间戳实现防抖
节流throttle
特定时间内,多次触发,只会执行一次
使用场景
滚动事件,上报滚动日志;滚动判断是否加载更多
节流的实现
1.定时器节流
通过一个变量作为开关,每次触发是先判断开关是否开着,开着才会执行,等到前面那个定时器执行完,才会重新打开开关;第一次开关是开着的,接到任务后,立马关闭开关,不接受新任务了;执行本次任务,等这次任务执行,再重新打开开关,再这之后触发事件又可以去执行了;这样就实现了一定时间内只会执行一次
<input type="text" class="input" />
<script>
var dom = document.querySelector(".input");
dom.addEventListener("input", throttle);
var flag = true; 初始开关开着
function throttle() {
if (!flag) return;
flag = false; 有任务了,立马关闭开关,不接受其他的任务了
setTimeout(() => {
console.log(888); 执行任务
flag = true; 执行完重新打开开关,在这之后触发input事件,才能执行任务
}, 1000);
}
</script>
2.lodash
3.时间戳
节流与防抖的异同
相同:
都是一定时间内多次触发,只会执行一次,都可以减少执行的次数
不同:
防抖可以保证一定时间内多次触发执行的是最后一次
而节流是第一次触发开始,就不再处理后面的触发,相当于触发无效,等到上一次触发处理完成,就可以处理新的触发了