什么是防抖和节流
举个例子,比如在进行百度搜索时,是等待用户时输入完成之后,才会在搜索框下显示,搜索内容,而不是当输入未完成的状态下进行搜索(这样会消耗大量的服务器资源)。
函数防抖
规定函数至少间隔多久执行
- 函数执行过一次后,在规定时间内不能再执行,否则推迟函数执行
- 下一次函数调用时,将清楚上一次定时器,并且使用setTimeout 重新计时
利用时间间隔,当事件触发的时间间隔很短的时候,就认为用户操作还处于未完成状态,推迟事件处理程序的执行。
<input type="text" id="input">
<script>
// 简单的防抖动函数
function debounce(func, wait) {
let timeout; // 定时器变量
return function() {
clearTimeout(timeout); // 每次触发时先清除上一次的定时器,然后重新计时
timeout = setTimeout(func, wait); // 指定 xx ms 后触发真正想进行的操作 handler
};
}
//事件处理程序
function realFunc(){
console.log("Success");
}
const input = document.getElementById('input');
input.addEventListener('keydown',debounce(realFunc,500));
//input.addEventListener('keydown',realFunc);
</script>
函数节流
规定函数在某时间段内最多执行一次
- 函数在规定时间内最多执行一次
- 下一次函数调用将清楚上一次的定时器
- 若函数执行的时间间隔 <= 规定时间间隔,则使用setTimeout 在规定时间后再执行
- 若函数执行时间间隔 > 规定时间间隔,则执行函数,并重新定时
<script>
//节流函数
function throttle(func,interval){
let timeout;
let startTime = new Date();
return function (){
clearTimeout(timeout);
let curTime = new Date();
if(curTime - startTime <= interval){
//小于规定时间间隔时,用setTimeout在指定时间后再执行
timeout = setTimeout(()=>{
func();
},interval)
} else {
//重新计时并执行函数
startTime = curTime;
func()
}
}
}
//事件处理程序
function realFunc(){
console.log('success')
}
window.addEventListener('scroll',throttle(realFunc,100));
//window.addEventListener('scroll',realFunc);
</script>
函数防抖和函数节流的对比
不管是函数节流还是函数防抖,减少的都是事件处理程序的调用频率,而不是时间的调用频率
何时使用函数防抖,何时使用函数节流?
- 当我们只需要处理最后一次触发事件时,用函数防抖。(例如:窗口大小变化,并不需要计算中间变化的过程,只需要窗口大小改变完成后的值)
- 当事件触发过于频繁,我们需要限制事件处理程序的调用频率时,用函数节流
传递事件对象
当我们使用节流函数或者防抖函数封装事件处理程序时,需要注意两个问题:
- 事件对象的传递
- this 的指向