JavaScript:节流与防抖

news2024/9/21 12:40:13

目录

一、前言

二、节流(Throttle)

1、定义

2、使用场景

3、实现原理

4、代码示例

5、封装节流函数 

三、防抖(Debounce)

1、定义

2、使用场景

3、实现原理

4、代码示例

5、封装防抖函数 

四、异同点总结


一、前言

在JavaScript中,通常需要用到一些事件,比如:按钮的click事件、输入框的keydown事件、鼠标的mousemove事件、浏览器的resize事件等。

这些事件都可能被高频触发,会不断的执行回调函数,从而导致一些资源浪费,影响前端性能;

如何优化呢?

JavaScript中的节流(Throttle)与防抖(Debounce)是两种优化高频执行函数的方法;

主要用于控制函数执行的频率,从而减少不必要的资源消耗,提高页面性能;

二、节流(Throttle)

1、定义

节流是指,当事件被连续触发时,在设定的一段时间内,只执行一次该事件的回调函数

也就是说,执行一次事件的回调函数后,等到间隔时间结束,若再触发该事件,才会再执行该事件的回调函数;

将高频执行变成每隔一段时间执行

举个例子

  • 假设一个事件的间隔时间是3秒,当第一次触发了该事件,会执行该事件的回调函数,
  • 3秒间隔内,再触发该事件,并不会再执行该事件的回调函数;
  • 直到3秒钟过后,再触发该事件,才会再执行该事件的回调函数;

2、使用场景

(1)多次点击按钮

当一个搜索按钮被连续多次点击时,并不是每次点击都发送请求,会存在一个间隔时间,距上次点击完获取数据后,间隔几秒钟,再点击才会重新请求加载数据;

(2)频繁下拉刷新

同样的,当页面被频繁下拉刷新时,并不是每次下拉都发送请求重新加载数据,会存在一个间隔时间,距上次刷新完几秒钟后,再下拉才会重新请求加载数据;

3、实现原理

利用定时器setTimeout设置间隔时间;

  • 每次执行事件的回调函数,都会添加一个新的定时器,到了设定时间再清除这个定时器;
  • 通过判断定时器是否存在,即可得到设置的计时是否结束;
  • 若定时器存在(未被清除),说明计时还未结束,本次不执行事件的回调函数;
  • 若定时器不存在(已被清除),说明计时已经结束,本次要执行事件的回调函数;

4、代码示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>节流与防抖</title>
</head>

<body>
    <button class="zyl-button">点击按钮</button>
</body>
<script>
    // 获取button按钮
    var zyl_button = document.querySelector(".zyl-button");
    // 使用节流
    let timerId_1 = null;
    zyl_button.addEventListener("click", function () {
        if (!timerId_1) {
            console.log("使用节流,每间隔3秒,再点击按钮才会被执行!");
            timerId_1 = setTimeout(() => {
                timerId_1 = null;
            }, 3000);
        }
    })
</script>

</html>

  • 按钮第一次被点击,执行打印输出;
  • 接着连续点击不会打印输出;
  • 直到距离上一次3秒钟过后,再点击才会继续打印输出; 

5、封装节流函数 

对节流函数进行封装,可以在需要的地方直接调用;

// 节流函数
function throttle(fn, time) {
    let timerId_1 = null;
    return function (...args) {
        if (!timerId_1) {
            fn.apply(this, args);
            timerId_1 = setTimeout(() => {
                timerId_1 = null
            }, time);
        }
    };
}

在上述示例中使用封装的节流函数 :

<script>
    // 获取button按钮
    var zyl_button = document.querySelector(".zyl-button");

    // 点击按钮的回调函数
    function handleClick() {
        console.log(this);
        console.log("使用节流,每间隔3秒,再点击按钮才会被执行!");
    }
    // 点击按钮 使用节流函数
    zyl_button.addEventListener('click', throttle(handleClick, 3000));


    // 节流函数
    function throttle(fn, time) {
        let timerId_1 = null;
        return function (...args) {
            if (!timerId_1) {
                fn.apply(this, args);
                timerId_1 = setTimeout(() => {
                    timerId_1 = null
                }, time);
            }
        };
    }
</script>

三、防抖(Debounce)

1、定义

防抖:当事件被连续触发时,只有在最后一次触发事件后的延迟时间内没有再次触发,才会执行目标函数;

也就是说,事件被触发后,不会立即执行该事件的回调函数,若在该事件的延迟时间内,没有再触发该事件,则执行该事件的回调函数

将高频执行变成在最后一次执行

举个例子

  • 假设一个事件的延迟时间是3秒,当触发了该事件,则它的回调函数会在3秒后执行;
  • 在这延迟的3秒期间,如果又触发了该事件,则会重新开始计时3秒钟
  • 如果又触发,就再重新计时,再触发,再重新计时......;
  • 直到距离事件的触发时间(延迟时间),大于3秒钟,才会执行该事件的回调函数;

2、使用场景

(1)搜索框的输入搜索

每次输入内容都去请求数据,请求次数过多,非常浪费资源;可以设置一个输入延迟时间(1秒),输入内容1秒钟后,再去发送请求,获取搜索结果;通过减少请求次数,提升性能;

(2)文本编辑器的实时保存

没必要每次编辑内容都进行保存,同样可以设置一个延迟时间(3秒),编辑内容3秒钟后,再自动发送请求,保存数据;

3、实现原理

利用定时器setTimeout设置延迟时间;

  • 每次事件触发时,先判断是否有延时定时器;
  • 有则清除,没有则创建一个新的延时定时器;
  • 在延时定时结束后,才会执行回调函数;
  • 若延时时间未结束前(定时器存在),再次触发该事件,清除旧的定时器,并设置新的定时器,重新开始计时;

4、代码示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>节流与防抖</title>
</head>

<body>
    <input class="zyl-input" type="text"><br><br>
</body>
<script>
    // 获取input框
    var zyl_input = document.querySelector(".zyl-input");
    // 使用防抖
    let timerId_2 = null
    zyl_input.addEventListener("keydown", function () {
        if (timerId_2) {
            clearTimeout(timerId_2);
        }
        timerId_2 = setTimeout(() => {
            console.log("使用防抖,3秒延迟内,没有再次触发该事件,则该回调函数被执行!");
        }, 3000);
    })
</script>

</html>

  • 在文本框中输入内容,打印输出并不会立即执行;
  • 只有在输入停止3秒钟后才会打印输出;

5、封装防抖函数 

对防抖函数进行封装,可以在需要的地方直接调用;

// 防抖函数
function debounce(fn, time) {
    let timerId_2;
    return function (...args) {
        if (timerId_2) {
            clearTimeout(timerId_2);
        }
        timerId_2 = setTimeout(() => {
            fn.apply(this, args);
        }, time);
    };
}

在上述实例中使用防抖函数 :

<script>
    // 获取input框
    var zyl_input = document.querySelector(".zyl-input");

    // 输入内容的回调函数
    function handleInput() {
        console.log(this);
        console.log("使用防抖,3秒延迟内,没有再次触发该事件,则该回调函数被执行!");
    }
    // 输入内容 使用防抖函数
    zyl_input.addEventListener('keydown', debounce(handleInput, 3000));

    // 防抖函数
    function debounce(fn, time) {
        let timerId_2;
        return function (...args) {
            if (timerId_2) {
                clearTimeout(timerId_2);
            }
            timerId_2 = setTimeout(() => {
                fn.apply(this, args);
            }, time);
        };
    }
</script>

四、异同点总结

异同点节流防抖
相同点1.函数目标都是为了优化事件处理,减少不必要的函数调用;
2.应用场景用于处理频繁触发的事件,以减轻应用的性能负担;
3.实现方式都可以通过setTimeout定时器,设定时间间隔来实现;
不同点1.触发机制节流在设定的时间间隔内只执行一次函数;防抖则是在事件停止触发后执行一次函数;
2.执行时机节流在事件触发时立即执行,但可能在时间间隔的末尾执行一次;防抖则是在事件停止触发后执行一次;
3.适用场景节流适用于需要在一段时间内处理一次事件的场景,如定时刷新页面数据;防抖适用于需要在事件停止触发后执行一次操作的场景,如输入框的值变化;

=========================================================================

每天进步一点点~!

记录一下 节流和防抖 这两个重要的技术~~!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1939091.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI算法22-决策树算法Decision Tree | DT

目录 决策树算法概述 决策树算法背景 决策树算法简介 决策树算法核心思想 决策树算法的工作过程 特征选择 信息增益 信息增益比 决策树的生成 ID3算法 C4.5的生成算法 决策树的修剪 算法步骤 决策树算法的代码实现 决策树算法的优缺点 优点 缺点 决策树算法的…

深入解析HNSW:Faiss中的层次化可导航小世界图

层次化可导航小世界&#xff08;HNSW&#xff09;图是向量相似性搜索中表现最佳的索引之一。HNSW 技术以其超级快速的搜索速度和出色的召回率&#xff0c;在近似最近邻&#xff08;ANN&#xff09;搜索中表现卓越。尽管 HNSW 是近似最近邻搜索中强大且受欢迎的算法&#xff0c;…

Latex使用心得1

本周暑期课程大作业需要使用Latex模板&#xff0c;采用的是老师给的IEEE的格式。从最开始不知道Latex是什么&#xff0c;到摸索着把大作业的小论文排版完成&#xff0c;其中也有一些心得体会。写在这里记录一下&#xff0c;以便以后回来再看&#xff0c;有更多的思考沉淀。 1、…

视觉巡线小车——STM32+OpenMV(三)

目录 前言 一、OpenMV代码 二、STM32端接收数据 1.配置串口 2.接收数据并解析 总结 前言 通过视觉巡线小车——STM32OpenMV&#xff08;二&#xff09;&#xff0c;已基本实现了减速电机的速度闭环控制。要使小车能够自主巡线&#xff0c;除了能够精准的控制速度之外&#xff0…

Java周总结7.20day

一&#xff0c;异常 异常 &#xff1a;指的是程序在运行过程中报错&#xff0c;然后停止运行&#xff0c;控制台显示错误。 注意事项&#xff1a;异常本身是一个类&#xff0c;出现异常会创建一个异常类的对象并抛出&#xff0c; public class DemoTest { public static void …

python—爬虫爬取电影页面实例

下面是一个简单的爬虫实例&#xff0c;使用Python的requests库来发送HTTP请求&#xff0c;并使用lxml库来解析HTML页面内容。这个爬虫的目标是抓取一个电影网站&#xff0c;并提取每部电影的主义部分。 首先&#xff0c;确保你已经安装了requests和lxml库。如果没有安装&#x…

海思arm-hisiv400-linux-gcc 交叉编译rsyslog 记录心得

需要编译rsyslog,参考海思3536平台上rsyslog交叉编译、使用-CSDN博客和rsyslog移植&#xff08;亲测成功&#xff09;_rsyslog交叉编译-CSDN博客 首先下载了要用到的一些库的源码&#xff0c;先交叉编译这些库 原来是在centos6上交叉编译的&#xff0c;结果编译时报缺少软件要…

使用vue3模拟element-ui中el-tabs的实现

一. 最终实现 组件没有背景颜色, 为了凸显组件文字,才设置了背景颜色 二. 使用 <wq-tabs v-model"activeName" style"background:grey; padding: 20px"><wq-tab-pane label"User" name"first">User</wq-tab-pane&g…

多任务高斯过程数学原理和Pytorch实现示例

高斯过程其在回归任务中的应用我们都很熟悉了&#xff0c;但是我们一般介绍的都是针对单个任务的&#xff0c;也就是单个输出。本文我们将讨论扩展到多任务gp&#xff0c;强调它们的好处和实际实现。 本文将介绍如何通过共区域化的内在模型(ICM)和共区域化的线性模型(LMC)&…

驱动LSM6DS3TR-C实现高效运动检测与数据采集(10)----融合磁力计进行姿态解算

驱动LSM6DS3TR-C实现高效运动检测与数据采集.10--融合磁力计进行姿态解算 概述视频教学样品申请源码下载硬件准备DataLogFusion磁力计校准过程初始化磁力计MFX_Arithmetic_Init卡尔曼滤波算法演示 概述 MotionFX库包含用于校准陀螺仪、加速度计和磁力计传感器的例程。 将磁力计…

【网络】windows和linux互通收发

windows和linux互通收发 一、windows的udp客户端代码1、代码剖析2、总体代码 二、linux服务器代码三、成果展示 一、windows的udp客户端代码 1、代码剖析 首先我们需要包含头文件以及lib的一个库&#xff1a; #include <iostream> #include <WinSock2.h> #inclu…

swiftui中onChange函数的使用,监听变量的变化

在 SwiftUI 中&#xff0c;onChange 修饰符用于在指定值发生变化时执行某些操作。它允许你监听一个状态或绑定值的变化&#xff0c;并在变化发生时运行一些代码。这个功能非常适合需要对状态变化做出响应的场景。 使用示例&#xff1a; struct AppStorageTest: View {State p…

友力科技数据中心搬迁方案

将当前运行机房中的所有设备、应用系统安全搬迁至新数据中心机房&#xff0c;实现平滑切换、平稳过渡&#xff0c;最大限度地降低搬迁工作对业务的影响。 为了确保企事业单位能够顺利完成数据中心机房搬迁工作&#xff0c;我们根据实际经验提供了4个基本原则&#xff0c;希望能…

【Linux】编辑器vscode与linux的联动

1.vscode简单学习 vscode是编辑器&#xff0c;可以写各种语言的程序 下载链接&#xff1a;Download Visual Studio Code - Mac, Linux, Windows 来用一下vscode 我们保存了就能在我们的那个文件夹里面看到这个 这个就是编辑器&#xff0c;跟我们的文本文件好像差不多&#…

RPM、YUM 安装 xtrabackup 8 (mysql 热备系列一)包含rpm安装 mysql 8 配置主从

RPM安装 percona-xtrabackup-80-8.0.35-30.1.el7.x86_64.rpm 官网&#xff1a; https://www.percona.com/ 下载地址&#xff1a; https://www.percona.com/downloads wget https://downloads.percona.com/downloads/percona-distribution-mysql-ps/percona-distribution-mysq…

51单片机14(独立按键实验)

一、按键介绍 1、按键是一种电子开关&#xff0c;使用的时候&#xff0c;只要轻轻的按下我们的这个按钮&#xff0c;按钮就可以使这个开关导通。 2、当松开这个手的时候&#xff0c;我们的这个开关&#xff0c;就断开开发板上使用的这个按键&#xff0c;它的内部结构&#xff…

从千台到十万台,浪潮信息InManage V7解锁智能运维密码

随着大模型技术的深度渗透&#xff0c;金融行业正经历着前所未有的智能化变革。从“投顾助手”精准导航投资蓝海&#xff0c;到“智能客服”秒速响应客户需求&#xff0c;大模型以其对海量金融数据的深度挖掘与高效利用&#xff0c;正显著提升金融服务的智能化水准&#xff0c;…

Java:拦截器简介和应用示例(多个拦截器+校验token是否为空)

JAVA 拦截器 简介 拦截器和过滤器均可以拦截http请求&#xff0c;过滤器偏向于基础设施工作&#xff0c;拦截器偏向于业务&#xff0c;拦截器允许在执行Controller之前做验证预处理&#xff0c;在Controller执行之后对返回对象做加工处理。可以用于&#xff1a;权限检查、日志…

2014年全国大学生数学建模竞赛C题生猪养殖管理(含word论文和源代码资源)

文章目录 一、部分题目二、部分论文三、部分源代码四、完整word版论文和源代码 一、部分题目 2014高教社杯全国大学生数学建模竞赛题目 C题 生猪养殖场的经营管理 某养猪场最多能养10000头猪&#xff0c;该养猪场利用自己的种猪进行繁育。养猪的一般过程是&#xff1a;母猪配…

第3关 -- Git 基础知识

任务1: 破冰活动&#xff1a;自我介绍 任务2: 实践项目&#xff1a;构建个人项目 MeiHuaYiShu