防抖
防抖函數(shù)是指一定時間內(nèi),事件被頻繁觸發(fā),但只執(zhí)行一次。
應(yīng)用場景:
- input 輸入搜索時,當(dāng)用戶停止輸入的時候才驗證,節(jié)約 ajax 請求
- 滾動條滾動,窗口變化的時候,觸發(fā)事件
示例:
// 簡單的防抖動函數(shù)
function debounce(func, wait, immediate) {
let timeout; // 定時器
return function () {
clearTimeout(timeout); // 每次觸發(fā) scroll handler 時先清除定時器
timeout = setTimeout(func, wait); // 真正想進行的操作 handler
};
}
// 實際想綁定在 scroll 事件上的 handler
function realFunc() {
console.log("Success");
}
// 采用了防抖動
window.addEventListener("scroll", debounce(realFunc, 1000));
// 沒采用防抖動
window.addEventListener("scroll", realFunc);
節(jié)流
節(jié)流函數(shù)是指一定時間內(nèi)方法只執(zhí)行一次。
應(yīng)用場景:
- 鼠標(biāo)不斷點擊觸發(fā),mousedown(單位時間內(nèi)只觸發(fā)一次)
- 上拉、觸底加載更多
示例:
function throttle(fn, delay) {
let last = 0, // last為上一次觸發(fā)回調(diào)的時間
timer: any = null; // timer是定時器
return function () {
let context = this; // 保留調(diào)用時的this上下文
let args = arguments; // 保留調(diào)用時傳入的參數(shù)
let now = +new Date(); // 記錄本次觸發(fā)回調(diào)的時間
// 判斷上次觸發(fā)的時間和本次觸發(fā)的時間差是否小于時間間隔的閾值
if (now - last < delay) {
// 如果時間間隔小于我們設(shè)定的時間間隔閾值
// 則為本次觸發(fā)操作設(shè)立一個新的定時器
clearTimeout(timer);
timer = setTimeout(function () {
last = now;
fn.apply(context, args);
}, delay);
} else {
// 如果時間間隔超出了我們設(shè)定的時間間隔閾值
// 那就不等了,無論如何要反饋一次響應(yīng)
last = now;
fn.apply(context, args);
}
};
}
// 實際想綁定在 scroll 事件上的 handler
function realFunc() {
console.log("Success");
}
// 采用了節(jié)流
window.addEventListener("scroll", throttle(realFunc, 1000));
// 沒采用節(jié)流
window.addEventListener("scroll", realFunc);