前端常用算法(一):防抖+节流

目录

第一章 防抖

1.1 防抖(debounce)简介

1.2 应用场景

1.3 实现思路

1.4 手撕防抖代码

第二章 节流

2.1 节流(throttle)简介

2.2 应用场景

2.3 实现思路

2.4 手撕节流代码(方法:时间戳和计时器)

2.5 时间戳与计时器实现的区别

第三章 总结


第一章 防抖

1.1 防抖(debounce)简介

  • 场景:用户在一段时间频繁点击执行某个函数/事件,那么在这段时间,用户点击一次,计时器重新计时当在这段时间内用户没有触发该函数/事件时,该函数/事件会在这段时间结束时执行。
  • 应用示例理解:回城被打断,玩家残血准备回城,需要3s回城成功,但是在这个3s的过程中,玩家又重新点击了回城,导致3s回城重新计算,再等3s。

1.2 应用场景

  • 登录、发短信、发送post请求等按钮/事件避免用户点击太快,以致于发送了多次请求,需要防抖,最后一次发送请求即可;
  • 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖;
  • input输入框获取到value值不需要输入一个字符就获取一次,可以使用防抖,让其输入结束之后再获取其值
  • 文本编辑器实时保存,当无任何更改操作一秒后进行保存。
  • ……

1.3 实现思路

 

1.4 手撕防抖代码

function debounce(func,delay) {// 定义一个定时器timerlet timer = nullreturn function() {const that = thisconst args = arguments// 防抖核心:每次触发事件计时器都会重新计时clearTimeout(timer)timer = setTimeout(()=>{func.apply(that,args)},delay)}
}
  • 例子:

未调用防抖函数时:用户每在input输入/删除一个值,都会输出一个值;

    <input type="text" id="input"><script>let inputDom = document.getElementById('input')//获取输入框的输入内容inputDom.oninput = function(){console.log('this.value',this.value)}</script>

 

 

调用防抖函数后:用户在input输入/删除一个值delay之后才,会输出一个值

    let inputDom = document.getElementById('input')//func 是执行函数,delay 是事件执行的延迟时间,毫秒function debounce(func,delay) {// 定义一个定时器timerlet timer = nullreturn function() {const that = thisconst args = arguments// 防抖核心:每次触发事件计时器都会重新计时clearTimeout(timer)timer = setTimeout(()=>{func.apply(that,args)},delay)}}function handler() {console.log('this.value',this.value)}inputDom.addEventListener('input', debounce(handler, 1000))

第二章 节流

2.1 节流(throttle)简介

  • 场景:用户在一段时间频繁点击执行某个函数/事件,那么在这段时间,用户点击一次/多次(调用事件),都不会影响计时器执行,并且该函数/事件只执行一次。
  • 应用示例理解:技能冷却中,玩家在某种情况下使用了闪现这个技能,但是这个技能的冷却时间是120s,在这段时间里,玩家遇到危险,想要再使用闪现这个技能,频繁的点击它,但是并没用,闪现不会执行,计时器依然还在倒计时,等到120s倒计时为0才能再使用一次闪现的技能。

2.2 应用场景

  • 窗口调整
  • 页面滚动
  • 抢购和疯狂点击
  • 懒加载获取滚动条的位置
  • 鼠标连续不断地触发某事件(如点击),只在规定时间内触发一次
  • ……

2.3 实现思路

2.4 手撕节流代码(方法:时间戳和计时器)

// ---------------------节流1:使用时间戳---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle (func, delay) {//定义初始时间(开始触发事件的时间)let start = 0;return function () {const that = thisconst args = arguments// 获取当前时间戳let cur =Date.now()// 时间间隔大于延迟时间则进入if (cur - start >= delay) {//执行事件处理程序func.apply(that, args);//更新初始时间start = cur}}
}
// ---------------------节流2:使用定时器---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle(func, delay){// 自定义一个定时器var timer = null;return function(){var that = this;var args = arguments// timer为null表示可以发送请求了,否则还在请求中,不执行事件if(!timer){timer = setTimeout(function(){//执行事件处理程序func.call(that, args)//事件执行完后把定时器清除掉,下次触发事件的时候再设置timer = null;}, delay)}  }
}
  •  例子:

未调用节流函数时,每点击一次按钮,都会执行一次函数调用:

<button id="button1">发送了节流请求</button>
const button1Dom = document.getElementById('button1')
button1Dom.addEventListener('click',function(){console.log("节流:我发送了消息")
})

 使用节流函数之后,频繁的点击发送请求,它会在计时器结束之后再发,这段时间内点击发送一次请求之后,不会再发送请求:

const button1Dom = document.getElementById('button1')
// ---------------------节流1:使用时间戳---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle (func, delay) {//定义初始时间(开始触发事件的时间)let start = 0;return function () {const that = thisconst args = arguments// 获取当前时间戳let cur =Date.now()// 时间间隔大于延迟时间则进入if (cur - start >= delay) {//执行事件处理程序func.apply(that, args);//更新初始时间start = cur}}
}
// ---------------------节流2:使用定时器---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
// function throttle(func, delay){
//     // 自定义一个定时器
//     var timer = null;
//     return function(){
//         var that = this;
//         var args = arguments
//         // timer为null表示可以发送请求了,否则还在请求中,不执行事件
//         if(!timer){
//             timer = setTimeout(function(){
//                 //执行事件处理程序
//                 func.call(that, args)
//                 //事件执行完后把定时器清除掉,下次触发事件的时候再设置
//                 timer = null;
//             }, delay)
//         }  
//     }
// }
button1Dom.addEventListener('click',throttle(function(){console.log("节流:我发送了消息")
},1000))

频繁的点击,降低了发送的频率: 

 

2.5 时间戳与计时器实现的区别

最明显的区别就是在频繁点击的时候,会发现使用时间戳实现的节流会在调用的时候马上执行,而使用计时器实现会在时间段结束时执行

第三章 总结

  • 所谓防抖,就是指触发事件后,在 n 秒后函数才会执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间;节流,就是指连续触发事件,但是在 n 秒中只执行一次函数。
  • 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。

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

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

相关文章

MR300C工业无线WiFi图传模块 内窥镜机器人图像传输有线无线的两种方式

MR300C无线WiFi图传模使用方法工业机器人图像高清传输 ⚫ MR300C图传模块基于MIPS处理器实现&#xff0c;电脑/手机连接模块的WIFI热点或网口即可查看视频流 ⚫ 模块的USB 2.0 Host接口&#xff0c;可接入USB uvc摄像头/内窥镜默认输出的视频格式必须是MJPG ⚫ 模块支持接入摄…

计算机竞赛 图像识别-人脸识别与疲劳检测 - python opencv

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是…

在 PyTorch 中使用关键点 RCNN 进行人体姿势估计--附源码

人体姿态估计是计算机视觉领域的一个重要研究领域。它涉及估计人体上的独特点,也称为关键点。在这篇博文中,我们将讨论一种在包含人类的图像上查找关键点的算法,称为Keypoint-RCNN。该代码是使用 Pytorch 使用Torchvision库编写的。 假设您想要建立一名私人健身教练,可以通…

MongoDB升级经历(4.0.23至5.0.19)

MongoDB从4.0.23至5.0.19升级经历 引子&#xff1a;为了解决MongoDB的两个漏洞决定把MongoDB升级至最新版本&#xff0c;期间也踩了不少坑&#xff0c;在这里分享出来供大家学习与避坑~ 1、MongoDB的两个漏洞 漏洞1&#xff1a;MongoDB Server 安全漏洞(CVE-2021-20330) 漏洞2…

SpringBoot + Vue 微人事(十二)

职位批量删除实现 编写后端接口 PositionController DeleteMapping("/")public RespBean deletePositionByIds(Integer[] ids){if(positionsService.deletePositionsByIds(ids)ids.length){return RespBean.ok("删除成功");}return RespBean.err("删…

工业视觉相机镜头选型方法

一、相机选型 1、首先&#xff0c;根据检测需求确定选用黑白/彩色、面阵/线阵相机&#xff0c;接口类型一般选择GigE 2、确定检测精度要求&#xff08;最小特征尺寸mm&#xff09;、视野范围&#xff0c;一个测量精度对应几个像素数&#xff08;一般取3-5&#xff09; 3、计…

GPT法律领域

法律领域 LaWGPT Github: https://github.com/pengxiao-song/LaWGPT 简介&#xff1a;基于中文法律知识的大语言模型。 数据&#xff1a;基于中文裁判文书网公开法律文书数据、司法考试数据等数据集展开&#xff0c;利用Stanford_alpaca、self-instruct方式生成对话问答数据…

esp32c3 micropython oled实时天气信息

目录 简介 效果展示 代码 main.py ssd1306.py font.py 实现思路 简介 合宙esp32c3 micropython框架&#xff0c;只支持128*64 I2C oled ssd1306驱动我优化过的&#xff0c;与其他的不一样&#xff0c;为避免出错&#xff0c;使用我的驱动 把下面两个py文件放入单片机内…

SqlServer的with(nolock)关键字的用法介绍

举个例子 下面就来演示这个情况。 为了演示两个事务死锁的情况&#xff0c;我们下面的测试都需要在SQL Server Management Studio中打开两个查询窗口。保证事务不被干扰。 --1、 没有提交的事务&#xff0c;NOLOCK 和 READPAST处理的策略&#xff1a; --查询窗口一请执行如下…

【马蹄集】第二十三周——进位制专题

进位制专题 目录 MT2186 二进制&#xff1f;不同&#xff01;MT2187 excel的烦恼MT2188 单条件和MT2189 三进制计算机1MT2190 三进制计算机2 MT2186 二进制&#xff1f;不同&#xff01; 难度&#xff1a;黄金    时间限制&#xff1a;1秒    占用内存&#xff1a;128M 题目…

Kotlin的Map

在 Kotlin 中&#xff0c;Map 是一种键值对的集合数据结构&#xff0c;用于存储一组关联的键和值。Kotlin 标准库提供了 Map 接口和多种实现类&#xff0c;使得操作和处理键值对数据更加方便。下面详细描述 Kotlin 的 Map 的用法&#xff1a; 创建 Map Kotlin 提供了几种方式…

SQL力扣练习(十一)

目录 1.树节点(608) 示例 1 解法一(case when) 解法二(not in) 2.判断三角形(610) 示例 1 解法一(case when) 解法二(if) 解法三(嵌套if) 3.只出现一次的最大数字(619) 示例 1 解法一(count limit) 解法二(max) 4.有趣的电影(620) 解法一 5.换座位(626) 示例 …

同步jenkinsfile流水线(sync-job)

环境 变量&#xff1a;env&#xff08;环境变量&#xff1a;sit/dev/simulation/prod/all&#xff09;&#xff0c;job&#xff08;job-name/all&#xff09;目录&#xff1a;/var/lib/jenkins/jenkinsfile environment.json&#xff1a; [roottest-01 jenkinsfile]# cat env…

C++ string类的模拟实现

模拟实现string类不是为了造一个更好的轮子&#xff0c;而是更加理解string类&#xff0c;从而来掌握string类的使用 string类的接口设计繁多&#xff0c;故而不会全部涵盖到&#xff0c;但是核心的会模拟实现 库中string类是封装在std的命名空间中的&#xff0c;所以在模拟…

webpack5和webpack4的一些区别

自动清除打包目录 webpack4 // bash npm i clean-webpack-plugin -D //webpack.config.js const {CleanWebpackPlugin} require(clean-webpack-plugin); module.exports {plugins: [new CleanWebpackPlugin()} } webpack5 module.exports {output: {clean: true} } topLevel…

使用PostgreSQL构建强大的Web应用程序:最佳实践和建议

PostgreSQL是一个功能强大的开源关系型数据库,它拥有广泛的用户群和活跃的开发社区。越来越多的Web应用选择PostgreSQL作为数据库 backend。如何充分利用PostgreSQL的特性来构建健壮、高性能的Web应用?本文将给出一些最佳实践和建议。 一、选择合适的PostgreSQL数据类型 Pos…

【Vue】Mixin 混入

Vue Mixin 混入 1.简介 混入&#xff08;mixin&#xff09;提供了一种非常灵活的方式&#xff0c;来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项&#xff08;如data、methods、mounted等等&#xff09;。当组件使用混入对象时&#xff0c;所有混入对象的…

Java将时间戳转化为特定时区的日期字符串

先上代码&#xff1a; ZonedDateTime dateTime ZonedDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),zone ); //2019-12-01T19:01:4608:00String formattedDate dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd") ); //2019-12-…

.git内存清理方式

查看前15个大文件 git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -15 | awk {print$1})"删除文件夹&#xff08;public/housimg文件夹目录&#xff09; git filter-branch --tree-filter rm -rf publ…