函数的防抖与节流

97 阅读1分钟

函数防抖节流的原理

函数节流与函数防抖的原理非常简单,巧妙地使用 setTimeout 来存放待执行的函数,这样可以很方便的利用 clearTimeout 在合适的时机来清除待执行的函数。

作用

使用函数节流与函数防抖的目的,就是为了节约计算机资源,提升用户体验。

使用场景

  • 节流一般是用在必须执行这个动作,但是不能够执行太频繁的情况下,例如滚动条滚动时函数的处理,可以通过节流适当减少响应次数;
  • 防抖一般是用来,用户输入有操作时,暂时不执行动作,等待没有新操作时,进行相应响应,例如用户名输入校验的情况,可以等待用户输入完成后再发送请求去校验。

实现方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>函数的防抖与节流</title>
    <style>
        *{padding:0;margin:0}body{height:100vh;display:grid;place-content:center;background-color:#ddd}
        .btn-container{width:300px;display:flex;justify-content:space-around}
        .btn-container>button{background:0;box-sizing:border-box;padding:10px 20px;cursor:pointer;border-radius:20px}
        #antiShake{border:2px solid #007acc;color:#ec191b}#throttle{border:2px solid #ec191b;color:#007acc}
    </style>
</head>

<body>
    <div class="btn-container">
        <button id="antiShake">防抖😁</button>
        <button id="throttle">节流🤔</button>
    </div>
    <script>
        const antiShakeBtn = document.getElementById('antiShake')
        const throttleBtn = document.getElementById('throttle')
        function antiShakeFun() {
            // 点击按钮后,做些什么事儿······
            console.log("这是防抖函数");
        }

        function throttleFun() {
            // 点击按钮后,做些什么事儿······
            console.log("这是节流函数");
        }
        antiShakeBtn.onclick = debounce(antiShakeFun, 1000)
        throttleBtn.onclick = throttle(throttleFun, 1000)

        // 防抖函数
        function debounce(func, wait) {
            let timer;
            return function () {
                // 这边的 this 指向谁?
                let context = this;
                // arguments中存着e
                let args = arguments;
                if (timer) clearTimeout(timer);
                let callNow = !timer;
                timer = setTimeout(() => {
                    timer = null;
                }, wait)
                if (callNow) func.apply(context, args);
            }
        }
        // 节流函数
        function throttle(func, wait) {
            let timeout;
            return function () {
                let context = this;
                let args = arguments;
                if (!timeout) {
                    timeout = setTimeout(() => {
                        timeout = null;
                        func.apply(context, args)
                    }, wait)
                }
            }
        }
    </script>
</body>

</html>