防抖和节流
防抖和节流产生的原因
在用户进行操作时,可能会频繁的触发某些事件,因为回调函数的数量过多而处理不及,导致页面的卡顿、性能下降
这时就可以根据自己的需求,来选择用防抖或者节流来控制回调函数触发的频率,从而达到想要的效果
防抖(debounce)
触发了某个事件,会在n秒之后处理对应的回调函数,若在n秒之内再次触发该事件,则重新开始计时
function debounce (fn, time) { let timer return function (...args) { if (timer) { // 清除上一次的定时器 clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, args) }, time) } }
节流(throttle)
在n秒内事件的回调函数只会执行一次。也就是说,当第一次触发了事件之后会执行对应的回调函数,然后在n秒之内无论触发多少次都不会有响应,如果事件是一直连续不断的触发,那么回调函数执行的频率是每n秒执行一次
// 用时间戳实现,触发事件后,对应的回调函数会立即执行 function throttle1 (fn, time) { let pre = 0 return function (...args) { if (Date.now() - pre > time) { pre = Date.now() fn.apply(this, args) } } } // 用定时器实现,触发事件后,对应的回调函数会在设定的秒数之后执行 function throttle2 (fn, time) { let timer = null return function (...args) { if (!timer) { timer = setTimeout(() => { clearTimeout(timer) timer = null fn.apply(this, args) }, time) } } } // 结合时间戳和定时器实现 function throttle3 (fn, time) { let pre = 0 let timer = null return function (...args) { if (Date.now() - pre > time) { clearTimeout(timer) timer = null pre = Date.now() fn.apply(this, args) } else if (!timer) { timer = setTimeout(() => { fn.apply(this, args) }) } } }