草庐IT

防抖、节流的介绍

Donp1 2023-08-26 原文

目录

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

输入框连续输入的案例

滚动条案例

 二、什么是防抖、节流

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

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

三、总结


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

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

  • 输入框连续输入的案例

<!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 输入事件

        节流的使用场景:

  • 商品搜索列表、商品橱窗等
  • 用户滑动时 定时 / 定滑动的高度 发送请求 

        防抖和节流之间的差别:

        防抖可能用于无法预知的用户主动行为,如用户输入内容去服务端动态搜索结果。用户打字的速度等是无法预知的,具有非规律性。

        节流可能用于一些非用户主动行为或者可预知的用户主动行为,如用户滑动商品橱窗时发送埋点请求、滑动固定的高度是已知的逻辑,具有规律性。

        防抖是关注于最后一次的事件触发,而节流则是在规定的时间里只执行一次。

有关防抖、节流的介绍的更多相关文章

  1. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  2. H2数据库配置及相关使用方式一站式介绍(极为详细并整理官方文档) - 2

    目录H2数据库入门以及实际开发时的使用1.H2数据库的初识1.1H2数据库介绍1.2为什么要使用嵌入式数据库?1.3嵌入式数据库对比1.3.1性能对比1.4技术选型思考2.H2数据库实战2.1H2数据库下载搭建以及部署2.1.1H2数据库的下载2.1.2数据库启动2.1.2.1windows系统可以在bin目录下执行h2.bat2.1.2.2同理可以通过cmd直接使用命令进行启动:2.1.2.3启动后控制台页面:2.1.3spring整合H2数据库2.1.3.1引入依赖文件2.1.4数据库通过file模式实际保存数据的位置2.2H2数据库操作2.2.1Mysql兼容模式2.2.2Mysql模式

  3. Spring Cloud Gateway 服务网关的部署与使用详细介绍 - 2

    为什么需要服务网关传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网关,客户端只能在本地记录每个微服务的调用地址,当需要调用的微服务数量很多时,它需要了解每个服务的接口,这个工作量很大。有了网关之后,网关作为系统的唯一流量入口,封装内部系统的架构,所有请求都先经过网关,由网关将请求路由到合适的微服务。使用网关的好处1)简化客户端的工作。网关将微服务封装起来后,客户端只需同网关交互,而不必调用各个不同服务;(2)降低函数间的耦合度。一旦服务接口修改,只需修改网关的路由策略,不必修改每个调用该函数的客户端,从而减少了程序间的耦合性(3)解放开发

  4. ruby - Vim 详细介绍了 Rails 的自动完成功能 - 2

    我发现python的细节自动完成很好RubyonRails有类似的方法描述吗? 最佳答案 有篇不错的文章"UsingVIMasacompleteRubyonRailsIDE"其中引用rails.vim.这似乎是RailsforVIM的实际标准。(不过,我还没有使用过它,但很快就会尝试。)这允许你做很多与Rails相关的任务,但对自动完成没有帮助。还有一篇"RubyAutocompleteinVim"(遗憾的是不再可用)这就是您要搜索的内容。我不知道,理解Rails的所有插件魔法和元编程的东西是否足够聪明。它至少在vim的配置中提到了

  5. 华为防火墙简单介绍 - 2

    防火墙防火墙分类第一代防火墙:包过滤防火墙包过滤防火墙的缺点第二代防火墙:代理防火墙第三代防火墙:状态防火墙第四代防火墙:UTM防火墙第五代防火墙:下一代防火墙华为防火墙介绍安全策略防火墙的会话表防火墙分类第一代防火墙:包过滤防火墙属于第一代防火墙技术,在没有专用防火墙设备时,一般由路由器实现该功能。将网络上传送数据包的IP首部以及TCP/UDP首部,获取发送源的IP地址和端口号,以及目的地的IP地址和端口号,并将这些信息作为过滤条件,决定是否将该分组转发至目的地网络分组过滤的执行需要设置访问控制列表。访问控制列表也可以称为安全策略(简称策略)或安全规则(简称规则)。类似于进站检票的做法,符合

  6. Qt样式表之 QSS 语法介绍;QLineEdit、 - 2

     内容来自Qt样式表之QSS语法介绍-3YL的博客Qt样式表是一个可以自定义部件外观的十分强大的机制,可以用来美化部件。Qt样式表的概念、术语和语法都受到了HTML的层叠样式表(CascadingStyleSheets, CSS教程)的启发,不过与CSS不同的是,Qt样式表应用于部件的世界。类型选择器QPushButton匹配QPushButton及其子类的实例ID选择器QPushButton#okButton匹配所有objectName为okButton的QPushButton实例。 CSS常用样式1CSS文字属性注:px:相对长度单位,像素(Pixel)。pt:绝对长度单位,点(Point

  7. Android对话框的详细介绍(提示对话框,自定义对话框) - 2

    简介:我们都知道在Android开发中,当我们的程序在与用户交互时,用户会得到一定的反馈,其中以对话框的形式的反馈还是比较常见的,接下来我们来介绍几种常见的对话框的基本使用。前置准备:(文章最后附有所有代码)我们首先先写一个简单的页面用于测试这几种Dialog(对话框)代码如下,比较简单,就不做解释了一、提示对话框(即最普通的对话框)首先我们给普通对话框的按钮设置一个点击事件,然后通过AlertDialog.Builder来构造一个对象,为什么不直接Dialog一个对象,是因为Dialog是一个基类,我们尽量要使用它的子类来进行实例化对象,在实例化对象的时候,需要将当前的上下文传过去,因为我这

  8. 技术分享 | observer 资源水位介绍 - 2

    作者:郭斌斌爱可生DBA团队成员,负责项目日常问题处理及公司平台问题排查。本文来源:原创投稿*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。OceanBase集群界面会展示Observer的资源水位,今天简单了解一下资源水位的数值代表的含义以及关联参数现有test_1集群,只有一个sys租户Sys租户的资源配置:Cpu:2.5-5Memory:3G-3GUnit:1集群的资源水位信息以10.186.63.198为例,浅看一下cpu、内存、磁盘的含义以及相关联参数cpu:2.5/17核2.5代表observer上已经分配给租户的cpu核数,该数值是租户的MinCPU

  9. (一)专题介绍:移动端安卓手机改造成linux服务器&linux服务器中安装软件、部署前后端分离项目实战 - 2

    快捷目录前言一、涉及到的相关技术简介二、具体实现过程及踩坑杂谈1.安卓手机改造成linux系统实现方案2.改造后的手机Linux中软件的安装3.手机Linux中安装MySQL5.7踩坑实录4.手机Linux中安装软件的正确方法三、Linux服务器部署前后端分离项目流程1.前提准备(安装必要软件,搭建环境):2.前后端分离项目的详细部署过程:总结前言总体概述:本篇文章隶属于“手机改造服务器部署前后端分离项目”系列专栏,该专栏将分多个板块,每个板块独立成篇来详细记录:手机(安卓)改造成个人服务器(Linux)、Linux中安装软件、配置开发环境、部署JAVA+VUE+MySQL5.7前后端分离项目

  10. 涡旋光束基本概念介绍 - 2

    涡旋光束及其MATLAB实现前言涡旋光束的基本概念常见的涡旋涡旋光束涡旋光束的产生方法前言笔者新开一块专栏,专门用于讨论整理总结涡旋光束的相关内容,从基本的概念出发,推导相关的公式,并结合MATLAB进行相关的仿真,不清楚这个专栏会更新多少期,我会分享部分的代码,全部的代码有需要的话可以私聊我。当然大家对这个专栏感兴趣的话,欢迎积极交流。涡旋光束的基本概念​涡旋光束(vortexbeam)是指携带光学涡旋,具有exp(imϕ)exp(im\phi)exp(imϕ)相位分布的光束,其中mmm表示相位拓扑电荷数,ϕ\phiϕ是柱坐标下的方位角。之前的分享中笔者已经说明了部分的激光光束的表达式,想要

随机推荐