防抖函数的几种写法

19 阅读2分钟

普通防抖函数

作用:在短时间内发生高频次的鼠标点击事件时,只执行最后一次满足等待时间的点击事件。

实现方法

/**
 * 防抖函数
 * @params { Function } fn - 执行函数
 * @params { Number } [delay=300] - 延迟执行时间
 * @returns { Function } - 返回防抖处理后的函数
 */
const debounce = (fn, delay=300) => {
    let timeId = null
    // 获取经过防抖处理过后函数调用时传入的参数
    return function (...args) {
        clearTimeout(timeId)
        timeId = setTimeout(() => {
            timeId = null
            // 执行原函数,并传入参数
            fn.apply(this, args)
        }, delay)
    }
}

使用示例:

const handleClick = (value) => {
    console.log('按钮被点击了', value)
}
const debounceHandleClick = debounce(handleClick, 500)
document.getElementById('myButton').addEventListener('click', debouncedHandleClick(111));

// 多次点击多次后点击结果:按钮被点击了 111

立即防抖函数

作用:第一次触发就立即执行一次,之后在等待时间内无论触发多少次都不会执行,满足等待时间后解锁下一次触发执行。

/**
 * 立即执行防抖函数
 * @param {Funtion} fn - 需要防抖处理的函数
 * @param {Number} [delay=300] - 等待时间ms
 * @returns {Function} - 返回包装后的防抖函数
 */
const immediateDebounce = (fn, delay=300) => {
    let timeId = null
    let first = true
    return function(...args) {
        clearTimeout(timeId)
        // 立即执行
        if (first) {
            first = false
            fn.apply(this, args)
        }
        timeId = setTimeout(()=>{
            // 解锁下一次执行
            first = true
        }, delay)
    }
}

可选执行时机的防抖函数

可以通过参数决定使用普通函数还是立即执行函数

/**
 * 防抖函数 触发后等待设定时间,期间无触发才执行
 * @param {Funtion} fn - 需要防抖处理的函数
 * @param {Number} [delay=300] - 等待时间ms
 * @param {Boolean} [immediate=false] - 是否立即执行一次
 * @returns {Function} - 返回包装后的防抖函数
 */
const debounce = (fn, delay=300, immediate = false) => {
    let timeId = null
    return function (...args) {
        if (timeId) clearTimeout(timeId)
        // 是立即执行并且首次执行
        if (immediate && !timeId) {
            fn.aplly(this,args)
        }
        timeId = setTimeout(()=>{
            if (!immediate) {
                fn.aplly(this,args)
            }
            timeId = null
        }, delay)
    }
}