// 防抖函数 (Debounce)
function debounce(func, delay) {
let timer;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
// 节流函数 (Throttle)
function throttle(func, delay) {
let lastTime = 0;
return function() {
const nowTime = Date.now();
if (nowTime - lastTime >= delay) {
func.apply(this, arguments);
lastTime = nowTime;
}
};
}
// 防抖运用场景:
// 1. 搜索框输入建议:用户输入时,不必每次输入都发送请求,而是等待用户停止输入一段时间后,再发送请求获取建议,减少服务器压力。
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function() {
// 发送搜索请求
console.log('Searching:', this.value);
}, 300)); // 300ms 的防抖延迟
// 2. 窗口大小调整:窗口大小调整频繁触发 resize 事件,使用防抖可以减少事件处理频率,例如在窗口大小改变后重新计算布局。
window.addEventListener('resize', debounce(function() {
// 重新计算布局
console.log('Resizing window');
}, 200)); // 200ms 的防抖延迟
// 节流运用场景:
// 1. 滚动加载:页面滚动时,不断触发 scroll 事件,使用节流可以控制加载频率,例如每隔一段时间加载一部分数据。
window.addEventListener('scroll', throttle(function() {
// 加载更多数据
console.log('Scrolling and loading data');
}, 200)); // 200ms 的节流间隔
// 2. 鼠标移动跟踪/游戏:鼠标移动会频繁触发 mousemove 事件,使用节流可以降低事件处理频率,例如每隔一段时间记录一次鼠标位置。
const mouseTracker = document.getElementById('mouse-tracker');
document.addEventListener('mousemove', throttle(function(event) {
mouseTracker.textContent = `Mouse position: ${event.clientX}, ${event.clientY}`;
}, 100)); // 100ms 的节流间隔
// 3. 按钮点击防止重复提交: 防止用户快速多次点击按钮,导致重复提交表单或者触发多次事件。
const submitButton = document.getElementById('submit');
submitButton.addEventListener('click', throttle(function(event) {
// 提交表单
console.log('Submitting form');
// 一些其他的操作,例如禁用按钮,显示 loading 状态等
}, 500)); // 500ms 的节流间隔,防止用户在短时间内多次点击
关键区别和总结:
-
防抖 (Debounce): 在事件被触发后,设定一个定时器,如果在设定的时间内再次触发该事件,则清除前一个定时器并重新设定一个新的定时器。只有当事件停止触发一段时间后,才会执行真正的操作。 目的: 减少事件的触发频率,通常用于最后一次操作后才执行的场景。
-
节流 (Throttle): 在一段时间内,只允许事件执行一次。如果在设定的时间内再次触发该事件,则忽略该事件。 目的: 控制事件的触发频率,通常用于持续触发事件,但需要限制频率的场景。
选择哪个取决于你的具体需求:
- 如果只需要最后一次结果,例如搜索建议,使用防抖。
- 如果需要在一段时间内持续响应事件,但要控制频率,例如滚动加载,使用节流。