在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove 等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数。
通常这种情况下我们怎么去解决的呢?一般来讲,防抖和节流是比较好的解决方案。
防抖(debounce)
在n秒内连续触发事件时,每触发一次就重新计算执行时间
(每触发一次事件就触发一次函数,但只执行最后一次触发的函数)(在n秒内)
<input type="text" id="value" oninput="fn()" />
function debounce(fn, delay) {
let timer = null
return (...args) => {
clearTimeout(timer) // 清除定时器,重新计算执行时间
timer = window.setTimeout(() => {
// fn.call(this, ...args)
fn(...args)
}, delay);
}
}
let fn = debounce((e) => {
console.log(e.target.value);
}, 2000)
节流
在n秒内连续触发事件时,只生效一次事件(函数只执行一次)
function throttle(fn, delay) {
let timer = null
return (...args) => {
if(timer) return
timer = setTimeout(() => {
timer = null
fn(...args)
}, delay)
}
}
总结
防抖和节流的区别:防抖是将多次执行变为最后一次执行,节流是将多次执行变为每隔一段时间执行
防抖和节流各有特点,在不同 的场景要根据需求合理的选择策略。如果事件触发是高频但是有停顿时,可以选择防抖; 在事件连续不断高频触发时,只能选择节流,因为防抖可能会导致动作只被执行一次,界面出现跳跃。