JS的节流和防抖,搞懂它!

大家好,我是梅巴哥er。今天一起来搞懂JS的节流和防抖。不再犯难!


什么是节流和防抖?

  • 节流:比如点击按钮让盒子移动50px。第一次点击按钮,盒子开始移动,然后在盒子移动完这50px的距离前,你接着不停的点击按钮,但是盒子并不会移动超过50px的距离。等移动到50px的位置后,你再点击按钮,才能再次让盒子移动下一个50px。总结:第一次操作的时候,开始执行。第一次执行结束前,再怎么操作都无效。就像你要喝水,打开饮水机水龙头接了一杯热水。就赶紧关掉饮水机水龙头。等你要倒下一杯水的时候再打开水龙头放水,不会一直开着。这样节省水流,所以叫节流。
  • 防抖:还拿发送验证码为例。上来就不停的点按钮,结果它就不发送验证码。等你不点击了,它开始发送验证码。总结:一直操作都无效,在最后一次操作时,开始执行。连续操作多次,都只会在最后一次操作才开始执行。防止手抖不停的操作,所以叫防抖。

节流和防抖有啥区别?思路是什么?

  • 区别

    • 节流是一段时间内的第一次点击有效,其他点击都无效。
    • 防抖是一段时间内的最后一次点击有效,其他点击都无效。
  • 思路

    • 节流思路:给操作函数加一个节流阀。

      • 函数执行前,先打开节流阀。
      • 函数开始执行时,就关闭节流阀。
      • 函数执行结束,再打开节流阀。
    • 防抖思路:我先定一个推迟执行的时间(定时器),在这个时间内,你如果操作5次,我就把前面4次的操作都给清除掉(清除定时器触发的函数),不让前面4次的操作去执行。等推迟的时间到了,再执行你第5次的操作。


节流案例

效果图:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>节流</title>
    <style>
        * {
     
     
            margin: 0;
            padding: 0;
        }
        #box {
     
     
            width: 100px;
            height: 100px;
            background-color: pink;
            text-align: center;
            line-height: 100px;
        }
        #btn {
     
     
            margin-top: 5px;
        }
    </style>
</head>
<body>
    <div id="box"></div>
    <button id="btn">移动</button>
    <script>
        var flag = true; // ①初始状态,打开节流阀
        var num = 0; // 初始化点击的次数
        var box = document.getElementById('box');
        var btn = document.getElementById('btn');
        function animate(obj, target) {
     
      // 移动一大步的动画函数
        	// target是移动一大步的目标距离
            clearInterval(obj.timer);
            function move() {
     
      // 移动一小步
            	// step是移动一小步的距离
                var step = (target - obj.offsetLeft) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                
                if(obj.offsetLeft === target) {
     
     
                    flag = true; // ③移动到目标位置后,打开节流阀
                }
                obj.style.marginLeft = obj.offsetLeft + step + 'px';
            }
            obj.timer = setInterval(move, 50); // 50毫秒移动一小步
        }
        btn.addEventListener('click', function() {
     
     
            if(flag) {
     
      // 如果节流阀是打开的,执行下面的代码
                num++;
                flag = false; // ②点击一次后,关闭节流阀
                animate(box, num*50);
            }
            console.log(num, flag, box.offsetLeft) // 查看点击时的状态
        })
    </script>
</body>
</html>

防抖案例

效果图:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>防抖</title>
    <style>
        * {
     
     
            margin: 0;
            padding: 0;
        }
        #box {
     
     
            width: 100px;
            height: 100px;
            background-color: pink;
        }
        #btn {
     
     
            margin-top: 5px;
            margin-left: 20px;
        }
    </style>
</head>
<body>
    <div id="box"></div>
    <button id="btn">防抖</button>
    <script>
        function debounce(fn, delay) {
     
      // 防抖函数
            let handle;
            return function (e) {
     
     
                // 取消之前的延时调用
                clearTimeout(handle);
                handle = setTimeout(() => {
     
     
                    fn(e);
                }, delay);
            }
        }
        function move() {
     
     
            box.style.marginLeft = box.offsetLeft + 50 + 'px';
        }
        var box = document.getElementById('box');
        var btn = document.getElementById('btn');
        btn.addEventListener('click', debounce(move, 500))
    </script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/tuzi007a/article/details/113166610