防抖与节流

70 阅读1分钟

防抖(debounce):就是指触发事件后在 n 秒内函数只执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

  • 用户触发时间过于频繁,只取最后一次事件的操作。
  • 应用场景:搜索框输入,设定每次输入完毕 n 秒后发送请求,如果期间还有输入,则重新计算时间。
<script>
    const inp = document.querySelector("input")
    inp.oninput = debounce(function () {
        // this 默认指向 window,更改之后指向 input
        console.log(this, '0----')
    }, 1000)

    // 防抖函数
    function debounce(fn, t) {
        let timer;
        return function () {
            // 如果有定时器就清除
            if (timer) clearTimeout(timer)
            // 开启定时器
            timer = setTimeout(() => {
                // 箭头函数的 this 默认指向上一级的作用域 input
                // 使用 call 改变 this 指向
                fn.call(this)
            }, t)
        }
    }
</script>

节流(throttle):就是指连续触发事件,但是在 n 秒内只执行一次函数。比如:可以利用节流实现 1s 之内,只能触发一次鼠标移动事件。

  • 应用场景:
    • 提交表单(防重复提交)。
    • 控制高频事件执行次数。
    • 鼠标移动、页面尺寸发生变化,滚动条滚动等开销比较大的情况下。
<script
    const box = document.querySelector(".box")
    let i = 1;

    function mouseMove() {
        // this 默认指向 window
        box.innerHTML = ++i
    }

    function throttle(fn, delay) {
        let timer = 0
        // return 函数产生一个闭包
        return function () {
            // 如果 timer 有值的话,就不执行
            if (timer) return
            timer = setTimeout(() => {
                // 使用 call 改变 this 指向
                fn.call(this);
                // 将 timer 设置为 0
                timer = 0
            }, delay)
        }
    }

    box.addEventListener('mousemove', throttle(mouseMove, 1000))
</script>