節流是指連續觸發事件但在 n 秒內只執行一次函數。
使用場景
- 滾動加載更多
- 鼠標移動事件
- 按鈕頻繁點擊
- 遊戲中的按鍵處理
function throttle(func, delay, options = {}) {
let timeoutId = null;
let lastTime = 0;
const { leading = true, trailing = true } = options;
return function(...args) {
const context = this;
const now = Date.now();
// 第一次執行控制
if (!lastTime && !leading) {
lastTime = now;
}
const remaining = delay - (now - lastTime);
if (remaining <= 0) {
// 可以執行
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
lastTime = now;
func.apply(context, args);
} else if (trailing && !timeoutId) {
// 設置延遲執行
timeoutId = setTimeout(() => {
lastTime = !leading ? 0 : Date.now();
timeoutId = null;
func.apply(context, args);
}, remaining);
}
};
}
防抖是指觸發事件後,在 n 秒後執行函數,如果在 n 秒內又觸發了事件,則會重新計算執行時間。
使用場景
- 搜索框輸入建議
- 表單驗證
- 窗口大小調整
- 文本編輯器自動保存
function debounce(func, delay, immediate = false) {
let timeoutId = null;
return function(...args) {
const context = this;
// 清除之前的定時器
if (timeoutId) {
clearTimeout(timeoutId);
}
// 立即執行模式
if (immediate && !timeoutId) {
func.apply(context, args);
}
timeoutId = setTimeout(() => {
// 非立即執行模式
if (!immediate) {
func.apply(context, args);
}
timeoutId = null;
}, delay);
};
}