一、防抖
在同一时间内 频繁触发事件,只处理最后一次
1、通过lodash库
document.querySelector('input').addEventListener('input',debounce(function () {
console.log('输入')
}, 500)
)
document.querySelector('input').addEventListener(
'input',
_.debounce(function () {
console.log('输入')
},500)
)
2、 自己封装
思路:
当事件发生,不立即执行事件回调。给个500毫秒后执行事件回调(定时器),在500毫秒内
再次触发事件,先取消上次的定时器,再重新开启一个定时器。
过程:
第一次事件触发 setTimeout(function() { 回调 },500)
事件又触发了一次 clearTimeout取消上一次的定时器,再重开一个定时器
function debounce(fn, t) {
let setId // 用于存储定时器的ID
return function () {
clearTimeout(setId) // 清除之前的定时器
setId = setTimeout(function () { // 设置新的定时器
fn() // 执行传入的函数
}, t)
}
}
二、节流
在同一时间内 频繁触发事件,只执行一次
1、通过lodash库
document.querySelector('button').addEventListener(
'click',
_.throttle(function () {
console.log('发请求')
}, 3000)
)
2、 自己封装
思路:
当第一次事件发生,把回调函数放到定时器 setTimeout(function () {回调调用},1000) 并且设置开关 把开关状态为true
当第二次事件发生 ,判断开关状态 ,如果是false 可以处理当前回调,如果是 true返回
过程:
第一次事件触发 setTimeout(function () {回调调用},1000) ,一秒以内的事件都会被阻挡,直到flag变为false
function throttle(fn, t) {
let flag = false // 一开始 false表示没有任务执行
return function () {
if (flag) return // 如果已经有任务在执行,直接返回,不执行新的任务
flag = true // 标记有任务在执行
setTimeout(function () {
fn() // 执行传入的函数
flag = false // 任务执行完毕后,重置标记
}, t) // 延迟t毫秒后执行
}
}