防抖(debounce): 当持续触发事件时, 一定时间段内没有再触发事件, 事件处理函数才会执行一次, 如果设定时间到来之前, 又触发了事件, 就重新开始延时(一般用于实时搜索框)
节流(throttle): 当持续触发事件时, 保证在一定时间内只调用一次事件处理函数, 意思就是说, 假设一个用户一直触发这个函数且每次触发小于既定值, 函数节流会每隔这个时间调用一次(一般用于滚动条事件或者 resize 事件)
区别: 防抖是将多次执行变为最后一次执行, 节流是将多次执行变为每隔一段时间执行
防抖
(百度上面的包浆图片)
防抖的使用场景
- 登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖
- 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖
- 文本编辑器实时保存,当无任何更改操作一秒后进行保存
// 防抖
function debounce(fn, time, immediate) {
let timer = null
return function() {
if (!timer && immediate) {
fn.apply(this, arguments)
}
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, arguments)
}, time)
}
}
节流
(百度上面的包浆图片)
节流的使用场景
- 鼠标连续不断地触发某事件(如点击),单位时间内只触发一次;
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断。例如:懒加载;
- 浏览器播放事件,每个一秒计算一次进度信息等
// 节流
function throttle(fn, time, immediate) {
let timer = null
return function() {
if (immediate) {
fn.apply(this, arguments)
immediate = false
}
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, time)
}
}
}
时间戳版节流
// 时间戳
function throttle(fn, time, immediate) {
let start = Date.now()
return function() {
if (immediate) {
fn.apply(this, arguments)
immediate = false
}
let now = Date.now()
if (now - start >= time) {
fn.apply(this, arguments)
start = Date.now()
}
}
}