0


防抖、节流的介绍

一、什么时候要用到防抖节流

    针一类类快速连续触发和不可控的高频触发问题,可以用节流和防抖。如通过滚动条的滚动来发起请求、通过输入文字来发起请求这一类的行为,下面用两个例子具体的给大家展示。
  • 输入框连续输入的案例

<!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>Document</title>
</head>

<body>
    <div>
        <span>输入文字发起请求:</span>
        <input type="text" id="input">
    </div>
    <script>
        // 通过id选择器获取到输入框实例对象
        const input = document.getElementById('input')
        // 给输入框对象绑定键盘输入事件
        input.oninput = function () {
            //利用定时器来模拟异步操作
            setTimeout(() => {
                // 使用日志输出来模拟ajax请求
                console.log("发起ajax请求" + ",时间戳为:" + new Date());
            }, 1000)
        }
    </script>
</body>

</html>

    通过运行的结果我们可以发现,输入123456,我们的请求也发送了6次。但实际上,我们并不关注输入1-5这5个字的结果,我们需要的是输入6之后的请求结果,那么前5次的请求都是无效的。如果请求需要的代价很大,就会造成较大的资源、带宽浪费甚至网页卡顿。对此我们就需要使用**防抖**的技术来解决这个问题。
  • 滚动条案例

<!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>Document</title>
    <style>
        .outer {
            height: 300px;
        }

        .inner {
            height: 1000px;
            /* 使用overflow:auto来开启滚动条 */
            overflow: auto;
        }
    </style>
</head>

<body>
    <div class="outer">
        <div class="inner"></div>
    </div>
    <script>
        window.onscroll = function () {
            //利用定时器来模拟异步操作
            setTimeout(() => {
                // 使用日志输出来模拟ajax请求
                console.log("发起ajax请求");
            }, 1000)
        }
    </script>
</body>

</html>

    这里将滚轮从最高处滑动到最后,可以发现请求发送了41条,同样的我们关注的是最后一条的请求结果,因此也造成了大量的资源浪费,这种情况下就可以使用**节流**来进行操作。

    又或者大家经常用到的京东,我们通过鼠标悬浮在左侧的菜单项上,动态的渲染右侧显示的内容。也是可以使用到**节流**,因为我们关注的只是我最后鼠标放置位置展示右侧的内容,使用**节流**可以节省一定的网络资源。

二、什么是防抖、节流

** (学习防抖和节流需要有闭包的知识基础)**

  • 防抖,顾名思义,防止抖动。用于将用户的操作行为触发转换为程序行为触发,防止用户操作的结果抖动。一段时间内,事件在我们规定的间隔 n 秒内多次执行,回调只会执行一次。

使用防抖来解决输入框案例造成的浪费现象:

<!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>Document</title>
</head>

<body>
    <div>
        <span>输入文字发起请求:</span>
        <input type="text" id="input">
    </div>
    <script>
        // 通过id选择器获取到输入框实例对象
        const input = document.getElementById('input')
        /* 防抖函数 */
        let debounce = function (callback, delay) {
            // 使用闭包的外部变量来定义定时器
            let timer;
            return function () {
                // 判断是否已经存在定时任务
                if (timer) {
                    /*
                     如果已有定时任务就将已有任务清楚,
                     再重新生成新的定时任务
                    */
                    clearTimeout(timer)
                }
                // 生成定时任务并赋值给timer
                timer = setTimeout(() => {
                    callback.call(this)
                }, delay)
            }
        }
        let ajax = function () {
            //利用定时器来模拟异步操作
            setTimeout(() => {
                // 使用日志输出来模拟ajax请求
                console.log("发起ajax请求" + ",时间戳为:" + new Date());
            }, 1000)
        }
        // 给输入框对象绑定键盘输入事件
        input.oninput = debounce(ajax, 1000)
    </script>
</body>

</html>

** 流程:**第一次输入的时候生成一个定时器,当到时间时发送请求。但在这个时间内如果用户再次输入文字的时候,将前一个定时器消除,重新生成一个新的定时器用新的参数发起请求,直到用户不再输入,定时任务完成将最后一次的请求发送给后端,获取到我们最终需要的数据。

    在下图里我们可以看到和最开始的案例已经有了不一样的结果,我们输入了6个字母最后只发送了一次的请求,恰巧是我们所需要的最后一次输入的结果。

  • 节流,顾名思义,控制流量。用于用户在与页面交互时控制事件发生的频率,一般场景是单位的时间或其它间隔内定时执行操作。一段时间内,事件在每次到达我们规定的间隔 n 秒时触发一次。

使用节流来解决滚动条案例造成的浪费现象:

<!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>Document</title>
    <style>
        .outer {
            height: 300px;
        }

        .inner {
            height: 1000px;
            /* 使用overflow:auto来开启滚动条 */
            overflow: auto;
        }
    </style>
</head>

<body>
    <div class="outer">
        <div class="inner"></div>
    </div>
    <script>
        /* 通过判断flag来实现节流 */
        let throttle = function (callback, delay) {
            // 判断依据
            let flag = true
            return function () {
                // 如果flag为false便忽略这次操作
                if (flag) {
                    /*  设定定时器,当任务执行时将flag恢复false,
                        允许下一次的事件触发
                    */
                    setTimeout(() => {
                        callback.call(this)
                        flag = true
                    }, delay)
                }
                //在定时任务执行之前,flag始终为false
                flag = false
            }
        }
        /* 通过时间来判断 */
        let throttling = function (callback, delay) {
            // 设置一个记录的时间,用以判断是否忽略操作
            let time = 0;
            return function () {
                // 创建当前时间,用以判断是否超过设定好的延迟
                let now = new Date()
                // 如果两次事件触发时间差大于设定好的毫秒数,则触发新的请求
                if (now - time > delay) {
                    // 执行回调函数
                    callback.call(this)
                    // 将记录的时间设置为这一次执行任务的时间
                    time = now
                }
            }
        }
        let ajax = function () {
            //利用定时器来模拟异步操作
            setTimeout(() => {
                // 使用日志输出来模拟ajax请求
                console.log("发起ajax请求");
            }, 1000)
        }
        window.onscroll = throttling(ajax, 3000)
    </script>
</body>

</html>

流程:设定一个时间,当到达规定时间后执行回调函数。在这个时间里,另外的事件触发则不生效。直到事件触发的时间差大于设定好的延迟时间。

将页面滑到底部,可以看到只执行了一次。

三、总结

** 防抖的使用场景:**

  • mousemove 鼠标滑动事件

  • input 输入事件

      **节流的使用场景:**
    
  • 商品搜索列表、商品橱窗等

  • 用户滑动时 定时 / 定滑动的高度 发送请求

      **防抖和节流之间的差别:**
    
      防抖可能用于无法预知的用户主动行为,如用户输入内容去服务端动态搜索结果。用户打字的速度等是无法预知的,具有非规律性。
    
      节流可能用于一些非用户主动行为或者可预知的用户主动行为,如用户滑动商品橱窗时发送埋点请求、滑动固定的高度是已知的逻辑,具有规律性。
    
      防抖是关注于最后一次的事件触发,而节流则是在规定的时间里只执行一次。
    
标签: 前端 html javascript

本文转载自: https://blog.csdn.net/Dpl0216/article/details/124363613
版权归原作者 Donp1 所有, 如有侵权,请联系我们删除。

“防抖、节流的介绍”的评论:

还没有评论