当前位置: 首页 > news >正文

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.适用场景节流适用于需要在一段时间内处理一次事件的场景,如定时刷新页面数据;防抖适用于需要在事件停止触发后执行一次操作的场景,如输入框的值变化;

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

每天进步一点点~!

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 主页目录导航
  • Unity XR Interaction Toolkit(VR、AR交互工具包)记录安装到开发的流程,以及遇到的常见问题(一)!
  • 如何将PDF转换成可以直接编辑的CAD图纸?
  • 前端下载文件流 出现乱码 解决方案
  • Random,ThreadLocalRandom,SecureRandom有什么区别
  • 【STM32 HAL库】全双工I2S+双缓冲DMA的使用
  • 科研绘图系列:R语言雨云图(Raincloud plot)
  • 【云原生】Prometheus 服务自动发现使用详解
  • Linux入门攻坚——28、php、mysql基础
  • 实现图片拖拽和缩小放大功能。
  • Java:对比一个对象更新前后具体被修改了哪些值
  • sqlalchemy_dm
  • JS中的File(五):node.js中的file模块使用
  • pytest:4种方法实现 - 重复执行用例 - 展示迭代次数
  • Java周总结7.20day
  • Centos6.8 使用rpm安装mysql5.7
  • CODING 缺陷管理功能正式开始公测
  • Facebook AccountKit 接入的坑点
  • js作用域和this的理解
  • Mysql优化
  • React系列之 Redux 架构模式
  • tensorflow学习笔记3——MNIST应用篇
  • Vue 重置组件到初始状态
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 使用Gradle第一次构建Java程序
  • 微信小程序:实现悬浮返回和分享按钮
  • 数据可视化之下发图实践
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • ./configure,make,make install的作用
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .net core控制台应用程序初识
  • .NET MVC之AOP
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .NET大文件上传知识整理
  • .net实现客户区延伸至至非客户区
  • .NET学习教程二——.net基础定义+VS常用设置
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [ MSF使用实例 ] 利用永恒之蓝(MS17-010)漏洞导致windows靶机蓝屏并获取靶机权限
  • [000-01-011].第2节:持久层方案的对比
  • [20190113]四校联考
  • [4]CUDA中的向量计算与并行通信模式
  • [AR]Vumark(下一代条形码)
  • [AutoSar]BSW_Memory_Stack_003 NVM与APP的显式和隐式同步
  • [AX]AX2012 AIF(四):文档服务应用实例
  • [C#]将opencvsharp的Mat对象转成onnxruntime的inputtensor的3种方法
  • [CDOJ 1343] 卿学姐失恋了
  • [Deep Learning] 神经网络基础
  • [Golang] goroutine
  • [Java][算法 双指针]Day 02---LeetCode 热题 100---04~07
  • [Latex] \bibitem{} | .bbl 格式参考文献转换与获得