防抖和节流

55 阅读2分钟

防抖函数

当持续触发事件,一定时间内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

触发事件,一段时间内,没有触发 事件执行 肯定是定时器 (在设定的时间内,又一次触发了事件,重新开始延时,代表的就是重新开始定时器)

(那么意味着上一次还没有结束的定时器要清除掉,重新开始)

let timer;
timer = setTimeout(
    () => {
        // ...处理
    },
    delay
)
实际应用

使用echarts时,改变测览器宽度的时候,希望重新渲染; echarts的图像,可以使用此函数,提升性能。(虽然echarts里有自带的resize函数)

典型的案例:

  • 就是输入搜索,输入结束后n秒才进行搜索请求,n秒内又输入的内容,就里新计时。
  • 解决搜索的bug。
    // 获取输入框
    const nameIpunt = document.querySelector('.name');
    // 防抖函数
    function debounce(delay, callback) {
        let timer;
        return (value) => {
            if (timer) {
                // 如果上次定时器存在,清除上一次定时器
                clearTimeout(timer);
            }
            // 将timer赋值存储
            timer = setTimeout(() => {
                callback(value);
            }, delay)
        }
    }
    function show(v) {
        console.log(v)
    }
    const debounceFn = debounce(1000, show);
    nameIpunt.addEventListener('keyup', (e) => {
        debounceFn(e.target.value)
    });

节流函数

当持续触发事件的时候,保证一段时间内,只调用一次件处理函数,一段时间内只做一件事情。

典型的案例:

  • 表单的提交,鼠标不断点击触发,规定在n秒内多次点击只有一次生效。
    // 获取发送按钮
    const submitButton = document.querySelector('.submit');

    function clcik(delay, callback) {
        let timer;
        return (value) => {
            // 在没有定时器时,定义定时器执行一次
            if (!timer) {
                timer = setTimeout(() => {
                    callback(value);
                    // 一次过后,清除定时器
                    clearTimeout(timer);
                }, delay);
            }

        }
    }
    const clcikFu = clcik(1000, (v) => {
        console.log(v, '=v=')
    });
    submitButton.addEventListener('click', (e) => {
        clcikFu(Math.random());
    });