个人博客:haichenyi.com。感谢关注
一. 目录
二. 防抖(Debounce)
防抖(Debebounce)和节流(Throttle)都是前端开发中用于优化高频事件性能的两种技术。他们的核心目的是减少函数的不必要的调用频率,但实现方式和场景有所不同。
原理: 事件触发后,开始计时,若在规定时间内,没有再触发该事件,则执行事件。若在规定时间内,又触发了该事件,则重新计时。
适用场景: 输入框的搜索事件,窗口大小调整,按钮的点击事件等等
function debounce(func, delay) {
let timer;
return function (...args) {
//清空上一次的定时器
clearTimeout(timer)
timer = setTimeout(() => {
//绑定this关键字和参数,并立即执行
//apply,call,bind三者的区别,前面的博客中讲过了
func.apply(this, args)
}, delay);
}
}
// 使用示例
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function() {
console.log('发起搜索请求');
}, 500));
特点:
- 高频操作停止后才会执行
- 若高频操作不停止,则该事件永远不会执行
三. 节流(Throttle)
原理: 在规定时间间隔内,不论事件触发多少次,函数只会执行一次。
适用场景: 滚动事件(scroll)、鼠标移动(mousemove)、游戏中的射击频率限制等。
function throttle(func, delay) {
let lastTime;
return function (...args) {
let now = Date.now()
if (now - lastTime >= delay) {
func.apply(this, args)
lastTime = now
}
}
}
// 使用示例
window.addEventListener('scroll', throttle(function() {
console.log('处理滚动事件');
}, 200));
特点:
- 不管事件触发多少次,都按照固定频率执行,稀释执行的次数。
- 保证高频操作下函数周期性执行。
四. 进阶应用
(4.1)立即执行的防抖,第一次触发立即执行,后续触发防抖:
function debounce(func, delay) {
let timer;
return function (...args) {
//如果timer是空,则立刻执行
let immediately = !timer
//第一次调用timer就是空,则立刻执行,短时间内再次触发,清空上一次的定时器,
clearTimeout(timer)
if (immediately) {
func.apply(this, args)
}
timer = setTimeout(() => {
timer = null
}, delay);
}
}
(4.2)头节流(Leading):期望第一次触发立即执行
function throttle(func, delay) {
let lastTime = 0;
return function (...args) {
let now = Date.now()
// 计算剩余时间(若首次触发则剩余时间 <= 0)
let remaining = delay - (now - lastTime)
if (remaining <= 0) {
func.apply(this, args)
lastTime = now
}
}
}
(4.3)尾节流(Trailing):保证最后一次触发,逻辑会执行
function throttle(func, delay) {
let timer = null;
return function (...args) {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, args)
timer = null
}, delay);
}
}
}
五. 总结
特性 | 防抖 | 节流 |
---|---|---|
执行时机 | 高频事件结束后,规定时间内执行 | 高频事件按照频率执行 |
适用场景 | 输入框,提交按钮等 | 滑动事件,动画渲染 |
极端情况 | 持续触发,不会执行 | 持续触发时,函数按规律执行 |
防抖: 合并多次操作为一次,适合“最终状态”场景(如输入停止后搜索)。
节流: 稀释执行频率,适合持续高频事件(如滚动事件)。
推荐使用Lodash的方法,不需要自己手动去写,了解防抖节流的原理即可。