防抖
适用于需要防止快速重复事件引发问题的场景
应用场景:
- 搜索框输入提示:当用户在搜索框中输入内容时,我们不希望每次输入一个字符就发送一次请求,而是等用户停止输入一段时间后再发送请求。
- 窗口调整大小:当用户调整浏览器窗口大小时,resize 事件会频繁触发,使用防抖可以确保只在用户停止调整窗口大小后执行回调函数。
- 按钮点击提交:防止用户多次快速点击按钮提交表单,确保只有在用户最后一次点击后的一定时间内才执行提交操作。
js
// 防抖函数
function debounce(func, delay) {
// 定义一个变量,用于存储定时器 ID
let timer = null;
// 返回一个函数,用于执行防抖操作
return function (...args) {
// 如果之前有定时器,重新设置新的定时器
if (timer) clearTimeout(timer);
// 创建定时器,执行回调函数
timer = setTimeout(() => {
func.apply(this, args);
}, delay)
}
}
节流
适用于需要限制同一时间段内事件数量的场景。
应用场景:
- 滚动事件监听:当页面滚动时,scroll 事件会频繁触发,使用节流可以限制回调函数的执行频率,避免性能问题。
- 鼠标移动事件:当鼠标在页面上移动时,mousemove 事件也会频繁触发,使用节流可以减少不必要的计算和 DOM 操作。
- 轮询操作:比如每隔一段时间检查一次网络状态或更新数据,使用节流可以控制检查的频率。
js
// 节流函数
function throttle(func, delay) {
// 定义一个变量,用于存储定时器 ID
let timer = null;
// 定义一个变量,用于记录上一次执行回调函数的时间
let date = 0;
// 返回一个函数,用于执行节流操作
return function (...args) {
// 当前的时间戳
const now = Date.now();
// 剩余时间(可能大于0,也可能小于0)
const remain = delay - (now - date);
if(remain <= 0){
// 如果剩余时间小于等于0,立即执行函数
if(timer){
// 执行函数前先清除定时器
clearTimeout(timer);
timer = null;
}
// 执行函数
func.apply(this, args);
date = now;
}else if(!timer){
// 如果剩余时间大于0,并且没有定时器,创建一个定时器
timer = setTimeout(() => {
func.apply(this, args);
date = Date.now();
timer = null;
}, remain)
}
// 如果剩余时间大于0,且有定时器,则不执行函数 -- 实现节流
}
}