JavaScript:节流与防抖

目录

一、前言

二、节流(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 = nullzyl_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.mzph.cn/diannao/48556.shtml

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

相关文章

信息检索(39):Condenser: a Pre-training Architecture for Dense Retrieval

Condenser: a Pre-training Architecture for Dense Retrieval 摘要1 引言2 相关工作3 方法3.1 前提3.2 Transformer 编码器的问题3.3 Condenser3.4 Transformer 编码器的 Condenser 4 实验4.1 预训练4.2 句子相似度4.3 开放域问答检索4.4 Web search 检索 5 注意力分析6 结论 …

Adobe Premiere Pro(Pr)安装包软件下载

一、简介 Adobe Premiere Pro&#xff08;简称Pr&#xff09;是由Adobe公司开发的一款功能强大的视频编辑软件。它支持多平台使用&#xff0c;包括Windows和Mac系统&#xff0c;并且拥有良好的兼容性和高效的性能。Premiere Pro不仅提供了视频剪辑、特效添加、音频处理等基本功…

《从C/C++到Java入门指南》- 9.字符和字符串

字符和字符串 字符类型 Java 中一个字符保存一个Unicode字符&#xff0c;所以一个中文和一个英文字母都占用两个字节。 // 计算1 .. 100 public class Hello {public static void main(String[] args) {char a A;char b 中;System.out.println(a);System.out.println(b)…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 二进制游戏(200分)- 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线…

npm install时报错 reason: connect ETIMEDOUT

在VS code中导入新项目&#xff0c;执行npm install时报错&#xff1a; npm warn old lockfile Could not fetch metadata for antv/coord0.1.0 FetchError: request to https://registry.npmjs.org/antv%2fcoord failed, reason: connect ETIMEDOUT 150.242.56.251:443 npm w…

大数据之路 读书笔记 Day8 数据存储

回顾&#xff1a; 大数据之路 读书笔记 Day7 实时技术 简介及流式技术架构 大数据之路 读书笔记 Day6 离线数据开发之数据开发平台 数据存储 1 数据类型 实时任务在运行过程中&#xff0c;会计算很多维度和指标&#xff0c;这些数据需要放在一个存储系统中作为恢复或者关联使…

微信小程序开发:DOM 相关 API 使用详解

在微信小程序开发中&#xff0c;与传统的网页开发相比&#xff0c;由于安全性和性能考虑&#xff0c;访问 DOM&#xff08;文档对象模型&#xff09;是受限的。然而&#xff0c;微信小程序提供了一些特定的 API&#xff0c;使开发者能够处理和操作视图层&#xff0c;实现丰富的…

Transformer之Vision Transformer结构解读

论文地址 代码地址 写在前面 什么是Transformer呢&#xff1f;就是把符号向量化为Token&#xff0c; 再和位置编码求和或者做阿达玛积&#xff0c;最后送入一定层数的Attention Block构成的Encoder和Decoder&#xff0c;就完成了Transformer的基础功能。 那么&#xff0c;把上…

C基础函数——内存分配(未完)

在C语言中&#xff0c;内存管理是非常重要的一部分。C语言提供了几种不同的函数用于动态内存分配和释放&#xff0c;这些函数允许程序在运行时根据需要分配和回收内存。以下是C语言中常用的几个内存管理函数&#xff1a; malloc() void malloc(size_t size); 这个函数用于请求…

C++中枚举(enum)的用法和限制

在C中&#xff0c;枚举&#xff08;enum&#xff09;是一种用户定义的类型&#xff0c;它允许程序员为整数常量指定易于阅读的名字。枚举类型是由一组命名的整型常量组成的类型&#xff0c;每个常量都表示该类型的一个有效值。枚举在编程中常用于表示一组固定的值&#xff0c;如…

MySQL:mysql的数据类型

MySQL 作为一个流行的关系型数据库管理系统&#xff0c;支持多种数据类型以满足不同的数据处理和存储需求。正确理解和使用这些数据类型对于提高数据库性能、确保数据完整性和准确性至关重要。 MySQL 数据类型 数据类型定义了列中可以存储什么数据以及该数据怎样存储的规则。…

idea2019版本创建JavaWeb项目并配置Tomcat步骤

一、创建JavaWeb项目 1.新建项目File->New->Project 2. 选择JavaWeb应用在New Project窗口中选择Java后勾选Java EE中的Web Application后点击next即可 3.设置项目名称后点击finish即可 4.至此项目创建完成&#xff0c;检查文件是否齐全&#xff0c;开始配置Tomcat 二、…

IDEA工具中Java语言写小工具遇到的问题

一&#xff1a;读取excel时遇到 org/apache/poi/ss/usermodel/WorkbookProvider 解决办法&#xff1a; 在pom.xml中把poi的引文包放在最前面即可&#xff08;目前就算放在最后面也不报错了&#xff0c;不知道为啥&#xff09; 二&#xff1a;本地maven打包时&#xff0c;没有…

base SAS programing学习笔记(read raw files2)

使用COLUMN input和FORMATTED input读入固定位置的外部文件&#xff1b;如下图所示&#xff0c; 1.COLUMN input &#xff08;按列数读入外部文件数据&#xff09; 使用column input 不需要按从左到右的顺序读取外部文件的数值&#xff0c;可以是任意读取&#xff0c;也可以重…

LeeCode Practice Journal | Day18_Binary Tree06

530.二叉搜索树的最小绝对差 题目&#xff1a;530. 二叉搜索树的最小绝对差 - 力扣&#xff08;LeetCode&#xff09; 题解&#xff1a;代码随想录 (programmercarl.com) 验证搜索树的进阶&#xff0c;二叉树中的双指针&#xff0c;思考过程中发现容易弄混递归向下传播和向上回…

STM32F103定时器中断详解

目录 目录 目录 前言 一.什么是定时器 1.1 STM32F103定时器概述 1.2基本定时器 1.2通用定时器 1.3高级定时器 1.4 三种定时器区别 基本定时器&#xff08;Basic Timer&#xff09; 通用定时器&#xff08;General-Purpose Timer&#xff09; 高级定时器&#xff08;Advanced Ti…

ubuntu2204配置anacondacuda4090nvidia驱动

背景 某个机房的几台机器前段时间通过dnat暴露至公网后被入侵挖矿&#xff0c;为避免一些安全隐患将这几台机器执行重装系统操作&#xff1b; 这里主要记录配置nvidia驱动及cuda&anaconda。 步骤 大概分为几个步骤 禁用nouveau配置grub显示菜单install nvidia-driveri…

基于Python+Django,开发的一个在线教育系统

一、项目简介 使用Python的web框架Django进行开发的一个在线教育系统&#xff01; 二、所需要的环境与组件 Python3.6 Django1.11.7 Pymysql Mysql pure_pagination DjangoUeditor captcha xadmin crispy_forms 三、安装 1. 下载项目后进入项目目录cd Online-educ…

【Rust光年纪】解锁Rust语言核心库奥秘:加密、数字签名和数据库操作全面解析

从加密到数据库&#xff1a;探索Rust语言丰富的工具库生态系统 前言 在Rust语言开发中&#xff0c;使用合适的库可以极大地提高代码的安全性和效率。本文将介绍一些用于加密、数字签名、数据库连接等功能的Rust语言库&#xff0c;帮助读者快速了解其核心功能、使用场景以及安…

Ubuntu2204搭建ceph17

Ceph 环境初始化搭建Ceph 本次实验基于VMware17 节点IPstorage01192.168.200.161storage01192.168.200.162storage01192.168.200.163 环境初始化 初始化基础环境&#xff0c;三节点执行 #!/bin/bash# 定义节点信息 NODES("192.168.200.161 storage01 root" "…