在前端開發(fā)的過程中寥殖,我們經(jīng)常會(huì)需要綁定一些持續(xù)觸發(fā)的事件宙暇,如 resize推沸、scroll备绽、mousemove 等等,但有些時(shí)候我們并不希望在事件持續(xù)觸發(fā)的過程中那么頻繁地去執(zhí)行函數(shù)鬓催。
通常這種情況下我們?cè)趺慈ソ鉀Q的呢肺素?一般來講,防抖和節(jié)流是比較好的解決方案宇驾。
防抖(debounce)
在n秒內(nèi)連續(xù)觸發(fā)事件時(shí)倍靡,每觸發(fā)一次就重新計(jì)算執(zhí)行時(shí)間
(每觸發(fā)一次事件就觸發(fā)一次函數(shù),但只執(zhí)行最后一次觸發(fā)的函數(shù))(在n秒內(nèi))
<input type="text" id="value" oninput="fn()" />
function debounce(fn, delay) {
let timer = null
return (...args) => {
clearTimeout(timer) // 清除定時(shí)器课舍,重新計(jì)算執(zhí)行時(shí)間
timer = window.setTimeout(() => {
// fn.call(this, ...args)
fn(...args)
}, delay);
}
}
let fn = debounce((e) => {
console.log(e.target.value);
}, 2000)
節(jié)流
在n秒內(nèi)連續(xù)觸發(fā)事件時(shí)塌西,只生效一次事件(函數(shù)只執(zhí)行一次)
function throttle(fn, delay) {
let timer = null
return (...args) => {
if(timer) return
timer = setTimeout(() => {
timer = null
fn(...args)
}, delay)
}
}
總結(jié)
防抖和節(jié)流的區(qū)別:防抖是將多次執(zhí)行變?yōu)樽詈笠淮螆?zhí)行,節(jié)流是將多次執(zhí)行變?yōu)槊扛粢欢螘r(shí)間執(zhí)行
防抖和節(jié)流各有特點(diǎn)筝尾,在不同 的場(chǎng)景要根據(jù)需求合理的選擇策略捡需。如果事件觸發(fā)是高頻但是有停頓時(shí),可以選擇防抖筹淫; 在事件連續(xù)不斷高頻觸發(fā)時(shí)站辉,只能選擇節(jié)流,因?yàn)榉蓝犊赡軙?huì)導(dǎo)致動(dòng)作只被執(zhí)行一次损姜,界面出現(xiàn)跳躍庵寞。