JavaScript 中的防抖和节流,它们的区别是什么,以及如何实现?

在前端开发中,防抖(Debounce)节流(Throttle)是两种常用的优化高频率事件处理的技术。

它们能够有效减少事件处理函数的执行次数,从而提升页面性能和用户体验。

下面将详细解释这两种技术的概念、区别、实现方法以及在日常开发中的使用建议和注意事项。

一、防抖(Debounce)

概念:防抖是指在事件被触发后,等待一定的时间,如果在这段时间内没有再次触发该事件,则执行一次事件处理函数;如果在等待期间内事件再次被触发,则重新计时。

应用场景

  • 窗口调整大小(resize):用户调整窗口大小时,频繁触发resize事件,使用防抖可以只在用户停止调整后执行一次处理逻辑。
  • 输入框实时搜索:用户在输入框中输入内容时,频繁触发输入事件,使用防抖可以只在用户停止输入一段时间后才发送搜索请求。

实现

/*** 防抖函数* @param {Function} func - 需要防抖处理的函数* @param {number} wait - 等待时间(毫秒)* @param {boolean} immediate - 是否立即执行* @returns {Function} - 返回防抖处理后的函数*/
function debounce(func, wait, immediate = false) {let timeout; // 定义一个定时器变量return function(...args) {const context = this; // 保存当前上下文const later = () => {timeout = null; // 清空定时器if (!immediate) func.apply(context, args); // 如果不是立即执行,则执行函数};const callNow = immediate && !timeout; // 判断是否立即执行clearTimeout(timeout); // 清除之前的定时器timeout = setTimeout(later, wait); // 设置新的定时器if (callNow) func.apply(context, args); // 如果需要立即执行,则执行函数};
}// 使用示例
const handleResize = debounce(() => {console.log('窗口大小调整完成');
}, 300);window.addEventListener('resize', handleResize);

代码说明

  • debounce 函数接收一个函数 func、等待时间 wait 和一个布尔值 immediate
  • 返回一个新的函数,在该函数被调用时,会设置一个定时器 timeout,在 wait 时间后执行 func
  • 如果在 wait 时间内再次调用该函数,会清除之前的定时器并重新设置,从而实现防抖效果。
  • 参数 immediate 控制是否在第一次触发时立即执行函数。
二、节流(Throttle)

概念:节流是指在一定的时间间隔内,只执行一次事件处理函数。无论事件触发频率多高,处理函数都会按照固定的时间间隔执行。

应用场景

  • 滚动事件(scroll):用户滚动页面时,频繁触发scroll事件,使用节流可以限制处理函数的执行频率,提升性能。
  • 鼠标移动事件(mousemove):在拖拽操作中,频繁触发mousemove事件,使用节流可以减少处理次数。

实现

/*** 节流函数* @param {Function} func - 需要节流处理的函数* @param {number} wait - 时间间隔(毫秒)* @param {Object} options - 可选参数* @param {boolean} options.leading - 是否在开始时执行* @param {boolean} options.trailing - 是否在结束时执行* @returns {Function} - 返回节流处理后的函数*/
function throttle(func, wait, options = {}) {let timeout = null; // 定时器变量let lastArgs = null; // 上一次的参数let lastThis = null; // 上一次的上下文let lastCallTime = 0; // 上一次调用的时间const later = () => {lastCallTime = options.leading === false ? 0 : Date.now();timeout = null;func.apply(lastThis, lastArgs);if (!timeout) lastArgs = lastThis = null;};return function(...args) {const now = Date.now();if (!lastCallTime && options.leading === false) lastCallTime = now;const remaining = wait - (now - lastCallTime);lastArgs = args;lastThis = this;if (remaining <= 0 || remaining > wait) {if (timeout) {clearTimeout(timeout);timeout = null;}lastCallTime = now;func.apply(lastThis, lastArgs);} else if (!timeout && options.trailing !== false) {timeout = setTimeout(later, remaining);}};
}// 使用示例
const handleScroll = throttle(() => {console.log('页面滚动');
}, 200);window.addEventListener('scroll', handleScroll);

代码说明

  • throttle 函数接收一个函数 func、时间间隔 wait 和一个可选参数对象 options
  • 返回一个新的函数,在该函数被调用时,会根据时间间隔 wait 来决定是否执行 func
  • 参数 options.leading 控制是否在开始时立即执行,options.trailing 控制是否在结束时执行。
  • 通过记录上一次调用的时间和设置定时器,实现节流效果。
三、防抖与节流的区别
特性防抖(Debounce)节流(Throttle)
执行时机在事件停止触发后的一段时间内执行一次在固定的时间间隔内执行一次
适用场景输入框实时搜索、窗口调整大小等需要等待用户停止操作的场景滚动事件、鼠标移动事件等需要限制执行频率的场景
实现方式通过不断重置定时器,确保只有在最后一次触发后的一段时间内没有新的触发才执行通过记录上次执行时间,控制函数的执行频率
四、日常开发中的使用建议
  1. 合理选择防抖和节流

    • 对于需要等待用户停止操作的事件(如输入、窗口调整),使用防抖更为合适。
    • 对于需要限制执行频率的事件(如滚动、拖拽),使用节流更为合适。
  2. 优化用户体验

    • 在高频率触发的事件中,合理使用防抖和节流,可以避免因频繁执行导致的页面卡顿或性能问题。
    • 例如,在搜索框中输入内容时,使用防抖可以减少不必要的搜索请求,提高响应速度。
  3. 结合实际需求调整参数

    • 根据具体业务场景,调整防抖和节流的等待时间或时间间隔,以达到最佳效果。
    • 例如,对于快速滚动的页面,可以将节流的时间间隔设置为100ms,以平衡性能和响应速度。
五、实际开发过程中需要注意的点
  1. 内存管理

    • 确保在组件销毁或不再需要监听事件时,移除相应的事件监听器,防止内存泄漏。
    • 例如,使用 removeEventListener 移除绑定的防抖或节流函数。
  2. 函数上下文和参数传递

    • 在实现防抖和节流时,注意保持原函数的上下文 (this) 和参数,确保函数执行时的正确性。
    • 例如,使用 func.apply(this, args) 来调用原函数。
  3. 兼容性和性能

    • 在不同浏览器和设备上测试防抖和节流的效果,确保兼容性。
    • 避免在节流或防抖函数中执行过于复杂的逻辑,以免影响性能。
  4. 组合使用

    • 在某些复杂场景下,可能需要同时使用防抖和节流,根据具体需求灵活组合使用。

示例:在一个需要同时限制滚动事件频率和搜索输入延迟的场景中,可以分别对滚动事件使用节流,对搜索输入使用防抖。

// 节流处理滚动事件
const handleScrollThrottled = throttle(() => {console.log('滚动事件节流处理');
}, 200);window.addEventListener('scroll', handleScrollThrottled);// 防抖处理搜索输入
const handleSearchDebounced = debounce((query) => {console.log(`搜索内容: ${query}`);
}, 300);searchInput.addEventListener('input', (e) => {handleSearchDebounced(e.target.value);
});

通过合理地组合使用防抖和节流,可以在不同的事件场景中达到最佳的性能优化效果。

防抖和节流是前端开发中优化高频率事件处理的重要技术。

理解它们的概念、区别及实现方法,并在实际开发中合理应用,可以显著提升页面性能和用户体验。

在实际应用中,需根据具体场景选择合适的优化策略,并注意内存管理、函数上下文和参数传递等问题,以确保代码的健壮性和可维护性。

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

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

相关文章

解锁Netty:Channel更替与HashMap管理的奇妙联动

个人CSDN博客主页&#xff1a; java之路-CSDN博客 ( 期待您的关注 ) 目录 Netty 的 Channel 机制探秘 HashMap 在 Netty 中的角色 创建新 Channel 时的操作步骤 新 Channel 的创建流程 确定老 Channel 的标识 移除老 Channel 的具体方法 从 HashMap 中移除 关闭和回收老…

小白零基础如何搭建CNN

1.卷积层 在PyTorch中针对卷积操作的对象和使用的场景不同&#xff0c;如有1维卷积、2维卷积、 3维卷积与转置卷积&#xff08;可以简单理解为卷积操作的逆操作&#xff09;&#xff0c;但它们的使用方法比较相似&#xff0c;都可以从torch.nn模块中调用&#xff0c;需要调用的…

12.翻转、对称二叉树,二叉树的深度

反转二叉树 递归写法 很简单 class Solution { public:TreeNode* invertTree(TreeNode* root) {if(rootnullptr)return root;TreeNode* tmp;tmproot->left;root->leftroot->right;root->righttmp;invertTree(root->left);invertTree(root->right);return …

算法之 博弈问题

文章目录 巴什博弈292.Nim 游戏 尼姆博弈斐波那契博弈其他博弈1025.除数博弈 博弈问题&#xff0c;就是双方之间的PK,关注的重点是 谁先&#xff1f;以及A,B各自赢的条件 一般有数学问题&#xff0c;动态规划&#xff0c;搜索进行求解 巴什博弈 下面的这题Nim 游戏&#xff0c;…

Linux 安装 Ollama

1、下载地址 Download Ollama on Linux 2、有网络直接执行 curl -fsSL https://ollama.com/install.sh | sh 命令 3、下载慢的解决方法 1、curl -fsSL https://ollama.com/install.sh -o ollama_install.sh 2、sed -i s|https://ollama.com/download/ollama-linux|https://…

DDR原理详解

DDR原理详解 存储器主要分为只读存储器 ROM 和随机存取存储器 RAM两大类。 ROM&#xff1a;只读存储器 ROM 所存数据&#xff0c;一般是装入整机前事先写好的,整机工作过程中只能读出&#xff0c;ROM所存数据稳定&#xff0c;断电后所存数据也不会改变。 RAM&#xff1a;随机…

推荐一款 免费的SSL,自动续期

支持自动续期 、泛域名 、可视化所有证书时效性 、可配置CDN 的一款工具。免费5个泛域名和1个自动更新。 链接 支持&#xff1a;nginx、通配符证书、七牛云、腾讯云、阿里云、CDN、OSS、LB&#xff08;负载均衡&#xff09; 执行自动部署脚本 提示系统过缺少crontab 安装cro…

手写一个C++ Android Binder服务及源码分析

手写一个C Android Binder服务及源码分析 前言一、 基于C语言编写Android Binder跨进程通信Demo总结及改进二、C语言编写自己的Binder服务Demo1. binder服务demo功能介绍2. binder服务demo代码结构图3. binder服务demo代码实现3.1 IHelloService.h代码实现3.2 BnHelloService.c…

将 AMD Zynq™ RFSoC 扩展到毫米波领域

目录 将 AMD Zynq™ RFSoC 扩展到毫米波领域Avnet XRF RFSoC 系统级模块适用于 MATLAB 的 Avnet RFSoC Explorer 工具箱5G mmWave PAAM 开发平台突破性的宽带毫米波波束成形特征&#xff1a;OTBF103 Mathworks Simulink 模型优化毫米波应用中的射频信号路径 用于宽带毫米波上/下…

征程 6 相比征程 5 对算子支持扩展的具体案例讲解

引言 征程 6 相比于征程 5&#xff0c;在整体架构上得到了升级&#xff0c;相对应的&#xff0c;算法工具链的算子支持也得到了扩充&#xff0c;无论是算子支持的数量&#xff0c;还是 BPU 约束条件&#xff0c;征程 6 都有明显的加强&#xff0c;这就使得过去在征程 5 上无法…

蓝桥杯C语言组:博弈问题

概述 在编程的世界里&#xff0c;博弈问题就像是一场智力的“斗地主”&#xff0c;双方&#xff08;或者多方&#xff09;使出浑身解数&#xff0c;只为赢得最后的胜利。而蓝桥杯C语言比赛中的博弈问题&#xff0c;更是让无数参赛者又爱又恨的存在。它们就像是隐藏在代码森林中…

BS架构(笔记整理)

楔子.基本概念 1.在网络架构中&#xff1a; 服务器通常是集中式计算资源&#xff0c;负责处理和存储数据&#xff1b;客户机是请求这些服务的终端设备&#xff0c;可能是个人电脑或移动设备&#xff1b;浏览器则是客户机上用来与服务器交互的工具&#xff0c;负责展示网页内容…

【动态规划篇】:动态规划解决路径难题--思路,技巧与实例

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;动态规划篇–CSDN博客 文章目录 一.动态规划中的路径问题1.核心思路2.注意事项 二.例题讲解…

【Linux】深入理解linux权限

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;Linux 目录 前言 一、权限是什么 二、用户和身份角色 三、文件属性 1. 文件属性表示 2. 文件类型 3. 文件的权限属性 四、修改文件的权限属性和角色 1. …

嵌入式linux系统中VIM编辑工具用法与GCC参数详解

大家好,今天主要给大家分享一下,如何使用linux系统中的VIM编辑工具和GCC的参数详解。 第一:安装VIM 命令:sudo apt get install vim 第二:工作模式 普通模式:打开一个文件时的默认模式,按ESC返回普通模式 插入模式:i/o/a进入插入模式,不同在于在光标前后插入 可视…

【前端开发】HTML+CSS+JavaScript前端三剑客的基础知识体系了解

前言 &#x1f31f;&#x1f31f;本期讲解关于HTMLCSSJavaScript的基础知识&#xff0c;小编带领大家简单过一遍~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 …

蓝桥杯---数青蛙(leetcode第1419题)

文章目录 1.题目重述2.例子分析3.思路分析4.思路总结5.代码解释 1.题目重述 这个题目算是模拟这个专题里面的一类比较难的题目了&#xff0c;他主要是使用crock这个单词作为一个整体&#xff0c;让我们确定&#xff1a;给你一个字符串&#xff0c;至少需要多少个青蛙进行完成鸣…

WidowX-250s 机械臂学习记录

官网教程&#xff1a;Python Demos — Interbotix X-Series Arms Documentation 系统&#xff1a;Ubuntu20.04&#xff0c;ROS1 相关的硬件编译配置跳过 Python Demos 这些演示展示了使用 Interbotix Python Arm 模块的各种方法&#xff08;点击链接查看完整的代码文档&…

【CubeMX-HAL库】STM32F407—无刷电机学习笔记

目录 简介&#xff1a; 学习资料&#xff1a; 跳转目录&#xff1a; 一、工程创建 二、板载LED 三、用户按键 四、蜂鸣器 1.完整IO控制代码 五、TFT彩屏驱动 六、ADC多通道 1.通道确认 2.CubeMX配置 ①开启对应的ADC通道 ②选择规则组通道 ③开启DMA ④开启ADC…

集成右键的好用软件,支持多线程操作!

今天给大家分享一个超级实用的小工具&#xff0c;真的能帮上大忙呢&#xff01;这个软件是吾爱大神无知灰灰精心制作的&#xff0c;简直就是图片转换界的“小能手”。 它能一键把webp格式的图片转换成png格式&#xff0c;而且速度超快&#xff0c;完全不输那些付费的软件&#…