今天我们来聊两个前端开发中特别实用的技巧:防抖和节流。它们就像是我们网页的"刹车"和"限速"系统,能帮我们控制网页上的各种操作不要太频繁。
一、防抖:等你不抖了再干活
1. 什么是防抖?
想象一下电梯门:当有人进出时,门会一直开着,直到最后一个人进去后,门才会关上。防抖就是这个道理——它会等到你"停止抖动"(停止操作)后才执行一次。
2. 什么时候用?
- 搜索框输入(等用户输完再搜索)
- 提交按钮(防止用户连点)
- 窗口大小调整(等用户调整完再计算)
3. 代码怎么写?
// 提交表单的按钮
let btn = document.getElementById('btn');
btn.addEventListener('click', debounce(handle, 1000)); // debounce函数中的this指向btn
function handle(e) {
console.log('向后端发请求', this); // 通过显示绑定,将handle的this也指向btn
}
// 防抖核心代码
function debounce(fn, wait) {
let timer = null; // 用来记时的"沙漏"
return function(...args) {
clearTimeout(timer); // 每次有人点按钮,就把之前的沙漏重置
// 开启沙漏
timer = setTimeout(() => {
fn.call(this, ...args); // 沙漏漏完,才真正干活
}, wait);
};
}
4. 实现要点
- 闭包保存定时器:使用闭包保存
timer变量,确保每次触发都能访问到同一个定时器 - 清除上一次定时器:每次触发时先清除之前的定时器,确保只有最后一次触发有效
- this和参数处理:使用
call方法确保函数执行时的this指向正确,并通过剩余参数...arg传递所有参数(包括事件参数event)
二、节流:再急也得按节奏来
1. 什么是节流?
就像水龙头,你开得再大,水流也是均匀的。节流就是让频繁的操作变成有规律的执行,比如每2秒最多执行一次。
2. 什么时候用?
- 页面滚动加载更多
- 鼠标移动跟踪
- 游戏按键控制
3. 代码怎么写?
// 绑定滚动事件
window.addEventListener('scroll', throttle(checkPosition, 200)); // throttle函数中的this指向window
function handle(e) {
console.log('向后端发请求', this); // 通过显示绑定,将handle的this也指向window
}
// 节流核心代码
function throttle(fn, wait) {
let lastTime = 0; // 上次执行的时间
return function(...args) {
const now = Date.now(); // 现在的时间
// 如果距离上次执行已经超过等待时间
if (now - lastTime >= wait) {
fn.call(this, ...args); // 可以执行了
lastTime = now; // 更新上次执行时间
}
};
}
4. 实现要点
- 时间戳记录:使用
Date.now()记录当前时间,利用闭包记录上一次执行时间 - 时间差判断:只有在当前时间与上一次执行时间的差值大于等待时间时,才执行
fn函数并更新上一次执行时间 - this和参数处理:和防抖类似,使用
call方法确保函数执行时的this指向正确,并通过剩余参数...arg传递所有参数
三、生活小例子帮你理解
-
防抖:就像你妈妈叫你吃饭,你总是说"马上来",最后妈妈等到你5分钟没再说"马上来"了,才真的把饭端上桌。
-
节流:就像你玩游戏按技能键,按得再快,技能也是有冷却时间的,不能无限放。
四、两者简单对比
| 防抖 | 节流 | |
|---|---|---|
| 特点 | 等你不操作了才执行 | 固定时间执行一次 |
| 例子 | 搜索框输入完才搜索 | 游戏角色移动 |
| 效果 | 只执行最后一次 | 均匀执行 |
五、实战小贴士
-
表单提交:防抖+禁用按钮双保险最好
button.addEventListener('click', debounce(() => { button.disabled = true; // 先禁用按钮 submitForm().finally(() => { button.disabled = false; // 完成后启用 }); }, 500)); -
滚动加载:用节流效果更好
window.addEventListener('scroll', throttle(loadMore, 300)); -
搜索建议:防抖最适合
searchInput.addEventListener('input', debounce(fetchSuggestions, 300));
记住这两个小技巧,能让你的网页变得更流畅,用户体验更好!刚开始可能不太习惯,多用几次就熟练啦!