防抖那些事儿
🔹 什么是防抖?
防抖的作用是:
👉 在一段时间内,只让最后一次触发的函数真正执行。
换句话说:如果一个动作被频繁触发(比如用户输入、窗口滚动),只有最后一次触发才会真正执行函数,中间的触发都会被“取消”。
🔹 使用场景
输入框搜索:用户一直在输入时,不要频繁发送请求,而是等用户停下输入后一段时间再发送。
窗口大小调整 (resize):用户拖动浏览器大小时,不要一直执行计算,等用户调整完后再执行一次。
按钮点击:防止按钮在短时间内被频繁点击,导致多次请求。
🔹 实现原理
防抖的核心就是用一个 定时器 setTimeout:
每次触发事件时,先把上一次的定时器清掉 clearTimeout(timer);
重新设置一个新的定时器,等待设定的时间;
如果在设定时间内没有新的触发,就执行函数。
🔹 手写防抖函数
function debounce(fn, delay) {let timer = null;return function(...args) {// 如果有上一个定时器,清掉if (timer) clearTimeout(timer);// 重新计时timer = setTimeout(() => {fn.apply(this, args); // 保证 this 和参数不丢失}, delay);}
}
🔹 使用示例
比如输入框搜索:
function search(value) {console.log("发送请求:", value);
}const debounceSearch = debounce(search, 500);// 模拟输入事件
document.getElementById("input").addEventListener("input", (e) => {debounceSearch(e.target.value);
});
👉 效果:只有在用户停止输入 500ms 后,才会触发一次 search。
🌰 例子 1:搜索框输入
function search(query) {console.log("发送请求:", query);
}const debounceSearch = debounce(search, 500);document.getElementById("search").addEventListener("input", (e) => {debounceSearch(e.target.value);
});
👉 用户狂敲键盘,只会在停下 500ms 后才真正发送一次请求。
🌰 例子 2:窗口大小调整(resize)
function handleResize() {console.log("窗口大小改变了", window.innerWidth, window.innerHeight);
}window.addEventListener("resize", debounce(handleResize, 300));
👉 浏览器窗口调整时会触发上百次 resize,但加上防抖后,只会在调整结束 300ms 后执行一次。
🌰 例子 3:按钮点击防重复提交
function handleClick() {console.log("按钮被点击了");
}const debounceClick = debounce(handleClick, 1000);document.getElementById("btn").addEventListener("click", debounceClick);
👉 用户疯狂点按钮,只有最后一次点击会生效,避免多次请求。
🌰 例子 4:表单实时验证
function validateInput(value) {console.log("验证输入:", value);
}const debounceValidate = debounce(validateInput, 400);document.getElementById("username").addEventListener("input", (e) => {debounceValidate(e.target.value);
});
👉 用户输入时不用每敲一个字都去校验,而是停顿一会再去校验。
🌰 例子 5:滚动监听(scroll)
function handleScroll() {console.log("滚动位置:", window.scrollY);
}window.addEventListener("scroll", debounce(handleScroll, 200));
👉 滚动事件触发非常频繁,防抖可以让它只在滚动结束时触发一次。
🔹 总结
防抖就是:
⏳ “等你停下来,我才执行”。
所以适合:
搜索输入
表单验证
窗口大小变化
滚动监听
按钮点击防多次触发
🔹 和节流 (throttle) 区别
防抖 (debounce):只执行最后一次。
节流 (throttle):一段时间内只执行一次(比如每隔 1s 执行一次)。