防抖:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
举个例子,坐电梯的时候,如果电梯检测到有人进来(触发事件),就会多等待 10 秒,此时如果又有人进来(10秒之内重复触发事件),那么电梯就会再多等待 10 秒。在上述例子中,电梯在检测到有人进入 10 秒钟之后,才会关闭电梯门开始运行,因此,“函数防抖”的关键在于,在 一个事件 发生 一定时间 之后,才执行 特定动作。
场景有:敲键盘就是一个每天都会接触到的防抖操作;登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖;调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖;文本编辑器实时保存,当无任何更改操作一秒后进行保存
思路:
每次触发事件时都取消之前的延时调用方法
function debounce(fn){
let timeout = null
return function(){
clearTimeout(timeout)
timeout = setTimeout(()=> {
fn.apply(this,arguments)
}, 500)
}
}
节流:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率(上一次点过之后,时间还没到,点了没用)
场景:scroll 事件,每隔一秒计算一次位置信息等;浏览器播放事件,每隔一秒计算一次进度信息等;input 框实时搜索并发送请求展示下拉列表,每隔一秒发送一次请求 (也可做防抖)。
思路:
每次触发事件时都判断当前是否有等待执行的延时函数
function throttle(fn) {
let canRun = true
return function() {
if (!canRun) return
canRun = false
setTimeout(()=>{
fn.apply(this, arguments)
canRun = true
}, 500)
}
}