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

手写防抖debounce

手写防抖debounce

应用场景

当需要在事件频繁触发时,只执行最后一次操作,可以使用防抖函数来控制函数的执行频率,比如窗口resize事件和输入框input事件;

这段代码定义了一个名为 debounce 的函数,它接收两个参数:fn(一个需要被防抖处理的函数)和 delay(一个延迟时间,单位是毫秒)。防抖(debounce)技术的主要目的是限制某个函数在一定时间内只执行一次,即使在这段时间内被频繁调用。这对于优化性能特别有用,比如避免因快速连续触发事件(如窗口调整大小、输入验证等)而造成的不必要的计算或 DOM 操作。

下面是代码的逐行解析:

  • let timer = null;:在这个函数作用域内声明一个变量 timer,并初始化为 null。这个变量将用来存储 setTimeout 的返回值,即一个可以被清除的计时器标识。
  • return function () { ... };debounce 函数返回一个新的匿名函数。这样做是因为我们希望返回一个经过防抖处理的新函数,而不是直接修改原函数。这种设计模式称为“闭包”,返回的函数能够访问外部函数(debounce)中的局部变量,如 timer
  • if (timer) clearTimeout(timer);:每次新的返回函数被调用时,首先检查 timer 是否存在且不为 null。如果存在,这意味着之前已经设置了一个定时器但尚未执行。此时,通过 clearTimeout 清除这个定时器,从而取消即将执行的 fn 调用。
  • timer = setTimeout(() => { fn.apply(this, arguments); }, delay);:这里设置一个新的定时器。当过了 delay 毫秒后,内部的箭头函数会被执行,它通过 apply 方法调用原始函数 fn,并确保 this 的上下文以及传给防抖函数的所有参数都能正确传递给 fnapply 的第一个参数 this 保证了在 fn 被调用时能保留正确的上下文环境,特别是当 fn 是对象的方法时;第二个参数 arguments 是一个类数组对象,包含了所有传入的参数。
function debounce(fn, delay) {let timer = null;return function () {
如果此时存在定时器的话,则取消之前的定时器重新记时if (timer) clearTimeout(timer);// 设置定时器,使事件间隔指定事件后执行timer = setTimeout(() => {fn.apply(this, arguments);}, delay);};}

应用

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><input type="text" id="myInput"><div id="display"></div>
</body>
<script>// 假设这是你的去抖动函数  function debounce(fn, delay) {let timer = null;return function () {if (timer) clearTimeout(timer);timer = setTimeout(() => {fn.apply(this, arguments);}, delay);};}// 这是你想要在输入框内容变化时执行的函数function updateContent(event) {// 获取输入框的值const inputValue = event.target.value;// 更新某个元素的内容(例如,一个显示框)displayElement.textContent = inputValue;}// 获取输入框和显示框的元素const inputElement = document.getElementById('myInput');const displayElement = document.getElementById('display');// 为输入框绑定事件监听器,并使用去抖动函数//将返回的函数绑定到相应的事件处理程序上,以实现防抖的效果。inputElement.addEventListener('input', debounce(updateContent, 500)); // 延迟500毫秒
</script></html>

展示

function debounce(fn,delay){
let timer=null;
return function(){
if(timer) clearTimeout(timer);
timer=setTimeout(()=>fn.apply(this,arguments),delay)
}}

相关文章:

手写防抖debounce

手写防抖debounce 应用场景 当需要在事件频繁触发时&#xff0c;只执行最后一次操作&#xff0c;可以使用防抖函数来控制函数的执行频率,比如窗口resize事件和输入框input事件&#xff1b; 这段代码定义了一个名为 debounce 的函数&#xff0c;它接收两个参数&#xff1a;fn…...

anaconda pycharm jupter分别是

Anaconda Anaconda是一个面向数据科学的Python发行版&#xff0c;它包含了Python解释器、conda包管理器、以及大量的科学计算和数据分析库。Anaconda的主要功能是提供一个易于管理的环境&#xff0c;用于安装、运行和更新Python包&#xff0c;同时支持创建和切换不同的Python环…...

【JMeter接口自动化】第3讲 Jmeter语言及外观配置

Jmeter语言配置 方法一&#xff1a;暂时生效&#xff0c;下次打开JMeter还会恢复默认配置 Jmeter安装后&#xff0c;默认语言是英文&#xff0c;可以在“选项”——“选择语音”中更改 方法二&#xff0c;修改配置文件&#xff0c;永久生效 修改jmeter.properties文件 Jmete…...

浅谈云原生安全

一、云原生安全的层级概念 "4C" Code-Container-Cluster-Cloud 二、云原生各个层级的安全实践有哪些&#xff1f; 1、针对于Cloud针对的是公有云层面&#xff0c;其实就一点 1、使用主账号子角色&#xff0c;赋予最小权限原则进行资源管理。 2、对于Cluster 1、从C…...

[线程与网络] 网络编程与通信原理(五): 深入理解网络层IP协议与数据链路层以太网协议

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …...

【Python】超时请求或计算的处理

超时机制 一般应用于处理阻塞问题 场景&#xff1a; 复杂度较大的计算&#xff08;解析&#xff09;某个数值、加解密计算等请求中遇到阻塞&#xff0c;避免长时间等待网络波动&#xff0c;避免长时间请求&#xff0c;浪费时间 1. requests 请求超时机制 reqeusts 依赖中的…...

前端 JS 经典:LRU 缓存算法

前言&#xff1a;什么是 LRU 呢&#xff0c;单词全拼 Least Recently Used&#xff0c;意思是最久未使用。这个算法是做缓存用的&#xff0c;比如&#xff0c;你要缓存一组数据&#xff0c;你要划分缓存块出来&#xff0c;因为不可能每个数据都做缓存&#xff0c;那么划出来的这…...

Python3 笔记:ljust、rjust 和 center

1、ljust() 方法返回一个原字符串左对齐,并使用空格填充至指定长度的新字符串。如果指定的长度小于原字符串的长度则返回原字符串。 ljust(self, width, fillchar , /) width -- 指定字符串长度。 fillchar -- 填充字符&#xff0c;默认为空格。 str1 sentence str2 word…...

恒压频比开环控制系统Matlab/Simulink仿真分析(SPWM控制方式)

介绍恒压频比的开环控制方法驱动永磁同步电机的转动&#xff0c;首先分析恒压频比的控制原理&#xff0c;然后在Matlab/Simulink中进行永磁同步电机恒压频比开环控制系统的仿真分析&#xff0c;最后将Simulink中的恒压频比控制算法生成代码加载到实际工程中进行工程实现。 一、…...

chatgpt4和文心一言的简单对比

功能1. 写一个ebpf程序监控udp延迟 文心一言 答案 编写一个完整的eBPF程序来监控UDP延迟涉及多个步骤&#xff0c;包括编写eBPF C代码、编译、加载到内核&#xff0c;以及用户空间程序来读取eBPF map中的数据。以下是一个简化的示例框架&#xff0c;展示如何使用eBPF来监控U…...

React 为什么使用map来渲染列表 而不是其他循环方法

1. 声明式与函数式编程 React强调声明式编程&#xff0c;这意味着你只需要关心代码“做什么”&#xff0c;而不是“怎么做”。.map()函数是一种高阶函数&#xff0c;它属于函数式编程范畴&#xff0c;能够返回一个新数组&#xff0c;这非常适合用于生成组件列表。 使用.map()…...

【Axure高保真】tab切换输入表单

今天和大家分享tab切换输入表单的原型模板&#xff0c;这个模板方便我们快速制作表单&#xff0c;里面包含了输入框、下拉列表、选择器共10多种常用的元件&#xff0c;后续也可以根据需要自行添加到中继器里。点击tab标签可以分类填写对应的内容&#xff0c;这个原型模板是用中…...

OrangePi AI Pro 测试体验

感谢CSDN活动提供的OrangePi AI Pro &#xff0c;之前一直用的树莓派&#xff0c;正好体验一下新的国产设备&#xff0c; 1、开机体验 整个设备包装不错&#xff0c;链接键盘、屏幕和鼠标&#xff0c;整体开机体验不错&#xff0c;内置OS不错&#xff0c;这个系统内嵌了中文输…...

【C++】:模板初阶和STL简介

目录 一&#xff0c;泛型编程二&#xff0c;函数模板2.1 函数模板概念2.2 函数模板格式2.3 函数模板的原理2.4 函数模板的实例化2.5 模板参数的匹配原则 三&#xff0c;类模板3.1 类模板的定义格式3.2 类模板的实例化 四&#xff0c;STL简介&#xff08;了解&#xff09;4.1 什…...

【软件开发】Java学习路线

本路径视频教程均来自尚硅谷B站视频&#xff0c;Java学习课程我已经收藏在一个文件夹下&#xff0c;B站文件夹同时会收藏其他Java视频&#xff0c;感谢关注。指路&#xff1a;https://www.bilibili.com/medialist/detail/ml3113981545 2024Java学习路线&#xff08;快速版&…...

git拉去代码报错“Failed to connect to 127.0.0.1 port 31181: Connection refused“

最近参与了一个新项目&#xff0c;在使用git clone 克隆代码时遇到了一个报错"fatal: unable to access ‘https://example.git/’: Failed to connect to 127.0.0.1 port 31181: Connection refused",今天就和大家分享下解决过程。 报错详情 在使用git clone 克隆…...

解读信创产业根基,操作系统发展历程

信创产业根基之一操作系统 操作系统是一个关键的控制程序&#xff0c;负责协调、管理和控制计算机硬件和软件资源。作为硬件的首要软件扩展&#xff0c;它位于裸机与用户之间&#xff0c;充当了两者之间的桥梁。通过其核心程序&#xff0c;操作系统高效地管理着系统中的各类资源…...

使用Python爬取华为市场游戏类APP应用

文章目录 1. 写在前面2. 接口分析3. 爬虫开发4. 下载链接获取 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守…...

【Oracle】修改已经存在的序列的当前值

前情提要 在oracle中一般使用序列来实现ID自增。但是oracle中序列维护的没有mysql那么好。只是单存的递增。 比如新建了一个序列&#xff0c;从1开始&#xff0c;每次递增1。此时我向数据库里插入一条id10的数据。那么在序列查询到10的时候&#xff0c;插入就会报错。 所以比较…...

记一次netty客户端的开发

背景 近日要开发一个tcp客户端程序去对接上游厂商的数据源&#xff0c;决定使用netty去处理&#xff0c;由于很久没有开发过netty了&#xff0c;顺便学习记录下 netty搭建 考虑到我们需要多个client去对接server服务&#xff0c;所以我们定义一个公共的AbstractNettyClient父…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

算术操作符与类型转换:从基础到精通

目录 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符&#xff1a;、-、*、/、% 赋值操作符&#xff1a;和复合赋值 单⽬操作符&#xff1a;、--、、- 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...