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

JavaScript实现防抖、节流【带思路】

目录

前言

防抖

节流

lodash

lodash的防抖

lodash的节流


前言

防抖节流一直是JavaScript异步处理中的经典问题,尽管现代已有许多库,我们可以很方便的使用它们,但是理解它们背后的原理还是十分重要的。

那么“防抖”与“节流”分别是什么意思呢?

  • 防抖:用户一段时间内频繁执行同一种操作,只执行最后一次。如:用户1s内连续点击“下载按钮”100次,最终只执行一次下载
  • 节流:用户一段时间内频繁执行同一种操作,但按照规定的最大时间限制规定期执行。如:用户10s内连续点击“更新按钮”100次,但最大时间限制为1s,最终只执行10次更新

简而言之,不管是“防抖”还是“节流”,它们使用的背景都是基于一段时间内频繁执行

防抖

防抖要满足:“对于一段时间内频繁的操作,只执行最后一次操作”,很容易想到使用“setTimeout”构建一个定时器,当一段时间过去后,最终只会执行一次setTimeout内的函数体。

那么当定时器在计时状态下,用户点击操作,计时器就要重新计时,因为这个时候可以理解为“一段时间”还没有过去,因为用户还在点击。“一段时间”过去的结束标志应该是“用户长时间没有执行点击操作

因此我们使用“闭包”存储这个计时器,当再次点击时clearTimeout并且重新计时即可

<body><input id="input" type="text" value="0"><button id="button">增加</button><script>const input = document.getElementById('input');const button = document.getElementById('button');// 防抖函数const debounce = (func, delay) => {let timer = null;const debounced = function (...args){const context = this;if (timer) {clearTimeout(timer);}timer = setTimeout(() => {func.apply(context, args);}, delay);}return debounced;}button.addEventListener('click', debounce(() => {input.value = parseInt(input.value) + 1;}, 500));</script>
</body>

效果:

你可能会有这种需求:“前1次点击操作需要进行防抖,后面就随客户玩去吧!”,那么我们可以给防抖方法添加cancel方法(只需要让delay为0即可),用来手动停止防抖

<body><input id="input" type="text" value="0"><button id="button">增加</button><script>const input = document.getElementById('input');const button = document.getElementById('button');// 防抖函数const debounce = (func, delay) => {let timer = null;const debounced = function (...args){const context = this;if (timer) {clearTimeout(timer);}timer = setTimeout(() => {func.apply(context, args);}, delay);}debounced.cancel = function() {clearTimeout(timer);timer = null;delay = 0;}return debounced;}const clickDebounce = debounce(() => {input.value = parseInt(input.value) + 1;if (input.value >= 1) {clickDebounce.cancel();}}, 500);button.addEventListener('click', clickDebounce);</script>
</body>

效果

节流

节流要满足:“对于一段时间内频繁的操作,总会按照给定的最大时间限制定期执行操作”,我们仍然可以使用setTimeout来解决,如果用户的某一次点击中,timer的状态不为空,说明此时在一个执行周期内,直接return忽略即可。

<body><input id="input" type="text" value="0"><button id="button">增加</button><script>const input = document.getElementById('input');const button = document.getElementById('button');// 节流函数const throttle = (func, delay) => {let timer = null;const throttled = function (...args){const context = this;if (timer) {return;}timer = setTimeout(() => {func.apply(context, args);timer = null;}, delay);}return throttled;}button.addEventListener('click', throttle(() => {input.value = parseInt(input.value) + 1;}, 1000));</script>
</body>

效果

你可能会有这种需求:“前1次点击操作需要进行节流,后面就随客户玩去吧!”,那么我们可以给节流方法添加cancel方法(只需要让delay为0即可),用来手动停止节流

<body><input id="input" type="text" value="0"><button id="button">增加</button><script>const input = document.getElementById('input');const button = document.getElementById('button');// 节流函数const throttle = (func, delay) => {let timer = null;const throttled = function (...args){const context = this;if (timer) {return;}timer = setTimeout(() => {func.apply(context, args);timer = null;}, delay);}throttled.cancel = function() {clearTimeout(timer);timer = null;delay = 0;}return throttled;}const clickThrottle = throttle(() => {input.value = parseInt(input.value) + 1;if (input.value >= 1) {clickThrottle.cancel();}}, 1000);button.addEventListener('click', clickThrottle);</script>
</body>

效果

lodash

现在我们已初步实现了防抖和节流,但是当我们理解原理之后,我更推荐大家使用已有的库调用比较成熟的方法

Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。

其中就有debounce防抖throttle节流方法供我们使用,具体可以参考官网:

Lodash 简介 | Lodash中文文档 | Lodash中文网

lodash的防抖

语法:

_.debounce(func, [wait=0], [options=])

以下是官方的解释:

<body><input id="input" type="text" value="0"><button id="button">增加</button><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script><script>const input = document.getElementById('input');const button = document.getElementById('button');button.addEventListener('click', _.debounce(() => {input.value = parseInt(input.value) + 1;}, 500));</script>
</body>

lodash的节流

语法:

_.throttle(func, [wait=0], [options=])

以下是官方的解释:

<body><input id="input" type="text" value="0"><button id="button">增加</button><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script><script>const input = document.getElementById('input');const button = document.getElementById('button');button.addEventListener('click', _.throttle(() => {input.value = parseInt(input.value) + 1;}, 1000));</script>
</body>

http://www.dtcms.com/a/461594.html

相关文章:

  • 汇川高压变频器故障解析F79 F90
  • kanass入门到实战(13) - 如何通过评审,有效保障需求和用例的质量
  • 深度解析:Redis缓存三大核心问题(穿透/击穿/雪崩)的技术原理与企业级解决方案
  • 最专业网站建设哪家好微网站微名片
  • 上海兆越通讯闪耀第二十五届中国国际工业博览会
  • 车库到双子星:惠普的百年科技传奇
  • 网站防止恶意注册dedecms菜谱网站源码
  • 基于IoT的智能温控空调系统设计与实现
  • 网站开发常用的框架营销到底是干嘛的
  • 老题新解|组合数问题
  • Java 工具类详解:Arrays、Collections、Objects 一篇通关
  • Cucumber自学导航
  • docker案例
  • 网站如何做提现功能上海市城乡和住房建设厅网站
  • 南宁 网站建设 公司老吕爱分享 wordpress
  • python 矩阵中寻找就接近的目标值 (矩阵-中等)含源码(八)
  • 嵌入式Linux:线程中信号处理
  • docker启动容器慢,很慢,特别慢的坑
  • C#基础14-非泛型集合
  • 【22.1-决策树的构建1】
  • asp制作网站wordpress使用端口
  • 【机器学习】(一)实用入门指南——如何快速搭建自己的模型
  • 【数值分析】插值法实验
  • 地方门户网站的前途搜索引擎大全全搜网
  • 如何给oracle新建架构(schema)
  • 天地数码携手一半科技PLM 赋能应对全球市场,升级热转印色带研发能力
  • 构筑智能防线:大视码垛机如何重新定义工业安全新标准
  • iPhone17实体卡槽消失?eSIM 普及下的安全挑战与应对
  • 什么RPA可以生成EXE
  • 网站开发设计jw100交换链接的作用