一、防抖 Debounce
1 )简单描述
- 防止抖动,防止你抖动过程中,执行下一步,等你停止了,再执行下一步
- 场景:输入框,等输入停止或者间歇,才去做
- 监听一个输入框,文字变化后出发change事件
- 直接用keyup,则会频繁出发change事件
- 用户输入或暂停时,才触发change事件
- 注意,如果用户连续触发,清理之前的
2 )代码实现
js
const input = document.getElementById('input')
// 防抖 封装
function debounce(fn, delay = 500) {
// timer 是闭包中的
let timer = null
return function () {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
// 注意这里的this, 结合下面的调用,fn不能是箭头函数
fn.apply(this, arguments)
// fn(); // 这样也可以,但是不如上面全面
timer = null
}, delay)
}
}
input.addEventListener('keyup', debounce(function (e) {
console.log(e.target)
console.log(input1.value)
}, 600))
二、节流 Throttle
1 )简单描述
- 节流,节省交互沟通
- 按照时间节奏来,插队者无效
- 场景
- drag 或 scroll 期间触发某个回调,要设置一个时间间隔
- 拖拽一个元素,要随时拿到该元素被拖拽的位置
- 直接用drag事件,则会频繁触发,导致卡顿
- 节流的目的是无论拖拽速度多快,每隔一定时间才去触发一次
- 轮播图的左右按钮
- 关注/取消关注的点击
- drag 或 scroll 期间触发某个回调,要设置一个时间间隔
2 )代码实现
ts
const div = document.getElementById('div');
// 节流的封装
function throttle(fn, delay = 100) {
let timer = null
return function () {
if (timer) return;
timer = setTimeout(() => {
// 注意,这种写法,arguments是为了获取下面的e
fn.apply(this, arguments)
timer = null
}, delay)
}
}
div.addEventListener('drag', throttle(function (e) {
console.log(e.offsetX, e.offsetY)
}))
- 等当前结束再执行,可加哨兵变量或者直接使用 timer 来判断
- 一般而言100的delay即可,场景是 拖拽、滚动时展示 坐标
总结
- 节流:限制执行的频率,有节奏的执行,关注过程
- 防抖:限制执行次数,多次密集触发只执行一次,关注结果