彻底搞懂JavaScript防抖与节流

news2024/11/23 15:33:14

今天为大家带来一篇JS重难点的知识体系,这也是前端高薪必备的重难点知识,而且防抖与节流在各大企业前端面试过程中经常会考到的高频面试题!

为了更好的帮助大家理解防抖与节流,我们特意从我们的系统班(星辰班)中节选了两节课详细的讲解!放在钉钉群直播回放里面,大家可以看完这个文章之后,可以通过最底部的微信二维码添加助理老师,加入三十天计划群里学习!(如果你已经添加了助理老师,那还等什么,赶紧去问问老师,加入交流群学习吧!)

有同学反馈:

看了那么多面试题和答案,还不如老师一节课讲的通透,听了不过瘾还想继续听 ^_^

一、为什么需要防抖与节流

我们要了解什么是防抖与节流?这就需要回归到现实的应用场景来谈。

如果我们要监听浏览器滚动事件,或监听输入框值变化查询搜索结果等等,这些场景有个共同特点,频繁执行,然而我们不需要太频繁执行,比如滚动事件,间隔几百毫秒或者一秒执行回调就能满足业务需求,所以才有了节流和防抖的概念,目的是减少事件回调执行,提高浏览器性能。

接下来我们通过一个常见的防抖案例:搜索查询来展开讲解,帮助大家理解防抖。然后我们再通过一个常见的节流案例:滚动加载更多来展开讲解,帮助大家理解节流。

二、防抖案例:搜索查询

比如我们在一个表单中输入内容,JS通过监听输入框值的变化来查询搜索结果,我们会通过keyup事件来处理,当键盘弹起时就会触发keyup事件,在事件处理函数中发送请求处理查询结果。在我们输入内容时,会频繁的触发keyup事件,然而我们并不希望太频繁触发keyup事件处理函数发送请求查询。我们希望当我们抬起键盘间隔几百毫秒后再触发keyup事件处理函数发送请求查询(如果在间隔时间内再次触发keyup事件,就会把上一次的定时器清除,重新再计时)。因为频繁的触发增加了浏览器的性能消耗,同时也增加了对服务器的请求次数,增加服务器的压力。具体代码实现如下:

当我们以正常的速度在输入框中输入内容时,两种效果的前后对比

未添加防抖前的效效果

<body>
搜索查询:<input type="text" id="search" />
<script>
const search = document.getElementById("search");
var i = 0;
search.onkeyup = function () {
//处理查询内容....
console.log(i++);//每触发一次,i+1
};
</script>
</body>

添加防抖前的效效果

添加防抖代码后的效果<body>
搜索查询:<input type="text" id="search" />
<script>
const search = document.getElementById("search");
var i = 0;
var timer = null;
search.onkeyup = function () {
//如果之前的定时器还在,则清除
if (timer) {
clearTimeout(timer);
}
//在400毫秒后再触发
timer = setTimeout(function () {
//处理查询内容...
console.log(i++);
timer = null; //本次查询完成,则定时器清除,以方便下次查询处理
}, 400);
};
</script>
</body>

>每次键盘抬起都会触发keyup事件,但是keyup事件需要在400ms后才会处理查询操作,所以在下次触发keyup时,时间在400ms内,就会把上一次的定时器给清除了,本质上就没有触发查询操作。所以在所有电话号码输入完成后,400ms后就触发了一次查询操作。这样做的好处减少事件回调执行,提高浏览器性能。

三、什么是防抖及应用场景

防抖的概念

在连续的事件中,只需触发最后一次回调,也就是将几次操作合并为一此操作进行。原理是维护一个计时器,规定在delay(延迟)时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

应用场景

搜索框输入查询、手机号、邮箱验证输入检测。只需用户最后一次输入完,再发送请求

窗口大小resize。只需窗口调整完成后,计算窗口大小,防止重复渲染。

四、防抖函数的封装

<script>
   //fn为事件处理函数   delay延迟时间
   function debounce(fn, delay) {
       var timer = null;
       return function () {
           if (timer) {
               clearTimeout(timer);
          }
           timer = setTimeout(() => {
               fn.apply(this, arguments); //this和参数
               timer = null;
          }, delay);
      };
  }
</script>

五、节流案例:滚动加载更多

接下来我们通过滚动加载更多为案例来展开讲解,帮助大家理解节流。

当我们滚动浏览器的滚动条时,会频繁触发scroll事件。我们通过监听浏览器scroll事件来断判断滚动条位置,如果滚动条滚动到页面的最底部,则就会加载更多信息。因为滚动时会频繁触发scroll事件,就会造成频繁的判断滚动条位置。

而我们并不希望每次触发scroll事件都需要去判断滚动条的位置,来决定是否加载更多,我们希望能间隔一定时间(几百毫秒)再判断一次,然后决定是否加载更多。如果时间不够,啥处理也不做,这样就能减少浏览器性能的消耗。

滚动加载更多源理:

  • 可视区的高度 + 滚动条滚动高度 >=文档高度 (整个滚动高度) 时就触发加载更多信息

未添加节流处理前的效果

scroll事件函数中的代码,在scroll事件触发时会频繁的被执行,特别消耗性能

<script>
var i = 0;
window.onscroll = function () {
//会频繁的处理以下代码,特别消耗性能
console.log(++i);//测试被执行的次数
var scrollTop = document
.documentElement.scrollTop;
var clientHeight = document
.documentElement.clientHeight;
var scrollHeight = document
.documentElement.scrollHeight;
if (scrollTop + clientHeight + 10 >= scrollHeight) {
//满足以上条件,则加载更多数据
console.log("开始加载更多数据....");
}
};
</script>

添加节流处理后的效果

scroll事件中的代码,会在事件触发时,每隔100ms触发一次。

<script>
var i = 0;
var timer = null;
window.onscroll = function () {
if (timer) {
return;
}
timer = setTimeout(function () {
console.log(++i);//测试被执行的次数
var scrollTop = document
.documentElement.scrollTop;
var clientHeight = document
.documentElement.clientHeight;
var scrollHeight = document
.documentElement.scrollHeight;
if (scrollTop + clientHeight + 10 >= scrollHeight) {
//满足以上条件,则加载更多数据
console.log("开始加载更多数据....");
}
timer = null;
}, 100);
};
</script>

同样的布局,同样的效果,在未做节流处理和做了节流处理,两者效果上有很大的差异。从头部滚动到底部触发加载更多,未做节流处理,共触发了35次代码的执行,而做了节流处理的,只触发了6次代码的执行。

六、什么是节流及应用场景

什么是节流

使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。

节流应用场景

监听滚动事件判断是否到页面底部自动加载更多

搜索联想功能

DOM元素的拖拽功能实现

射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)

防止高频点击提交,防止表单重复提交;

七、节流函数的封装

<script>
   function throttle(fn, delay) {
       var timer = null;
       return function () {
           if (timer) {
               return;
          }
           timer = setTimeout(() => {
               fn.apply(this, arguments);//把this和参数传递过去
               timer = null;
          }, delay);
      };
  }
</script>

八、总结防抖与节流

不同点

节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数

防抖只是在最后一次事件后才触发一次函数。

应用场景

防抖应用场景

搜索框输入查询、手机号、邮箱验证输入检测。只需用户最后一次输入完,再发送请求

窗口大小resize。只需窗口调整完成后,计算窗口大小,防止重复渲染。

节流应用场景

监听滚动事件判断是否到页面底部自动加载更多

搜索联想功能

DOM元素的拖拽功能实现

射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)

防止高频点击提交,防止表单重复提交;

相同点

都可以通过使用 setTimeout 实现

降低回调执行频率。节省计算资源


防抖节流是JS阶段重要的教学内容,如果你正在学习JS或者已经在我们的三十天计划中完成了4个综合项目实战,那不妨可以听下这个课程体系,三十天计划群里还提供了算法、数组等知识体系!

更多完整JavaScript课程体系在我们的系统班里有完整的呈现,包含了JavaScript基础篇、重点、算法、原理、面试题、实战案例讲解!同时也为你提供了前端高级工程师成长体系!(详细看下图内容)

如果需要深度学习的同学可以点击下方链接了解详细的课程以及课程的报名方式!(,可以先领取以上推荐的几节JS课程学习,再来参与系统学习,不定期会推出活动,有大额优惠券推出,活动详情联系助理老师了解即可!)

Web 前端高级工程师系统课 | arry老师的博客-艾编程

如果你才开始学习前端,那么可以先学习我们的三十天计划(零基础的同学报名系统班同学可以和老师沟通制定学习计划,可以得到更快的成长!)

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

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

相关文章

[阶段4 企业开发进阶] 6. Dubbo

文章目录1 基础理论1.1分布式基础理论1.2 发展演变1.3 RPC2 Dubbo2.1 基本概念2.2 Dubbo架构2.3 环境搭建Windows环境安装教程Linux环境安装教程3 案例演示3.1 需求分析3.2 工程架构分包粒度3.3 创建模块3.4 使用Dubbo配置版注解版4 监控中心4.1 安装4.2 监控中心配置5 整合Spr…

Java中的成员内部类

一、什么是成员内部类 成员内部类就是定义在外部类成员位置(属性/方法的位置)的类。成员内部类就是个成员。 二、为什么要有成员内部类 使用场景&#xff1a;除了它的外部类&#xff0c;不会被其他类使用&#xff0c;就可以使用成员内部类。有两种情况&#xff1a;1.不可能有…

大数据面试之Spark Core常见题目

大数据面试之Spark Core常见题目 1 Spark任务的划分 1、Application&#xff1a;初始化一个SparkContext即生成一个Application。 2、Job&#xff1a;一个Action算子会生成一个Job&#xff0c;有多个Action算子就有多个Job。 3、Stage&#xff1a;Stage等于宽依赖的个数加1…

特殊符号(一)—反斜杠 ” \ “(旋转光标和倒计时的实现)

特殊符号一.功能1.功能一&#xff1a;续航符2.功能二&#xff1a;转义符二.旋转光标和倒计时一.功能 1.功能一&#xff1a;续航符 顾名思义&#xff0c;就是连续的意思&#xff0c;主要用于换行的时候&#xff0c;看例子 以上是一个简单的判断语句&#xff0c;如果if里面的判断…

Win10十二月更新系统讲了什么?

微软今天凌晨发布了win10系统12月最新的累积更新补丁&#xff0c;根据该公司的公告&#xff0c;更新 KB5021233 将版本号增加到构建 19042.2364 &#xff08;20H2&#xff09;、19043.2364 &#xff08;21H1&#xff09;、19044.2364 &#xff08;21H2&#xff09; 和 19045.23…

01-35-springcloud-zk-eureka-consul-cap-父工程

01-springcloud-入门理论等&#xff1a; 微服务 1、什么是微服务 微服务是一种架构风格一个应用拆分为一组小型服务每个服务运行在自己的进程内&#xff0c;也就是可独立部署和升级服务之间使用轻量级HTTP交互服务围绕业务功能拆分可以由全自动部署机制独立部署去中心化&…

产品外观设计一一素描

在反映产品外观设计时&#xff0c;应根据产品的不同功能选择反映方法&#xff0c;以便更清晰地表达创作者的设计理念。首先&#xff0c;我们应该运用透视图的规律性来构建空间框架结构&#xff0c;将镜头中的许多外观元素有机地结合起来&#xff0c;并根据设计科学地安排镜头中…

Portal数据清理过程说明

Portal门户集成平台作为统一的门户搭建和展现平台&#xff0c;提供综合门户、信息门户、应用门户、数据门户等不同类型门户的建设能力&#xff0c;可以为企业构建门户网站、内部业务中心&#xff0c;同时对企业文档资料进行整合、统一归档&#xff0c;对内部、外部提供资料。通…

基于微信小程序的劳务咨询系统设计与实现-计算机毕业设计

项目介绍 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于劳务咨询服务平台小程序当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了劳务咨询服务平台小程序&#xff0…

[附源码]计算机毕业设计第三方游戏零售平台Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…

互联网电商大厂的分布式事务使用案例

事务的原子性、持久性可确保在一个事务内&#xff0c;更新多条数据都成功/失败。在一个系统内部&#xff0c;我们可以使用数据库事务来保证数据一致性。那如果一笔交易&#xff0c;涉及到跨多个系统、多个数据库的时候&#xff0c;用单一的数据库事务就没办法解决了。 在之前大…

Altova MissionKit Enterprise 2023 SP1 Crack

屡获殊荣的 XML、JSON、SQL 和 UML 工具套件 以低于 2 个的价格获得 7 个 XML、JSON SQL 和 UML 工具&#xff01; Altova MissionKit 是面向信息架构师和应用程序开发人员的企业级 XML、JSON、SQL 和 UML 工具的软件开发套件。MissionKit 包括 Altova XMLSpy、MapForce、Styl…

Python 中的垃圾回收机制总结(1)

1.背景 对于Python来说&#xff0c;一切皆为对象&#xff0c;所有的变量赋值都遵循着对象引用机制。 程序在电脑上运行的时候&#xff0c;需要在内存中开辟出一块空间&#xff0c;用于存放运行时产生的临时变量&#xff0c;一方面&#xff0c;内存的容量是有限的&#xff1b;…

JNPF3.4.5消息模块:多渠道应用,配置灵活多样,满足更多使用场景

自11月15日&#xff0c;JNPF 3.4.5 JAVA版本上线&#xff0c;就受到了众多用户的广泛好评&#xff0c;此次更新为用户带来了不同以往的使用体验。 在本次更新中&#xff0c;所有工作流都可以实现自主配置消息模板的操作&#xff0c;同时包括站内信&#xff0c;也可以实现自主配…

sublime json美化

sublime 的插件 json美化感觉很难用&#xff0c;好多正常的json串都 不能正常解析 &#xff0c;自己写了一个json解析插件&#xff0c;此插件跟网上教程的json美化插件 不同的是&#xff1a; 只对json的特殊字符进行格式化 { [ ] } : , 这种不是很严格但是正好解决了我的问…

【Redis】Redis 持久化

文章目录概述RDB触发机制如何恢复 rdb 文件&#xff1f;RDB 优点&#xff1a;RDB 缺点&#xff1a;AOFAOF 优点AOF 缺点概述 Redis 是内存数据库&#xff0c;如果不将内存中的数据库状态保存到磁盘&#xff0c;那么服务器一旦进程退出&#xff0c;服务器中的数据库状态也会消失…

【C语言进阶】一文速通面试中的指针相关疑难杂症(内含模拟库函数 qsort 的实现)

目录 &#x1f947;前言&#x1f947;&#xff1a; 一、指向函数指针数组的指针&#x1f92f;&#xff1a; 1.书写格式&#x1f99a;&#xff1a; 2.指向函数指针数组指针示例&#x1f9a9;&#xff1a; 二、回调函数&#x1f9d0;&#xff1a; 1.回调函数的定义&#x1f99…

嵌入式软件工程师技能树——应用编程/网络编程/驱动开发/操作系统/计算机网络

文章目录Linux驱动开发1、Linux内核组成2、用户空间与内核的通讯方式有哪些&#xff1f;3、系统调用read/write流程4、内核态用户态的区别5、bootloader内核 根文件的关系6、BootLoader的作用7、BootLoader两个启动阶段1、汇编实现&#xff0c;完成依赖于CPU体系架构的设置&…

Win10安装Linux虚拟机-安装与使用

Win10安装Linux虚拟机-安装与使用 1、VMware 的下载 VMWare虚拟机软件是一个“虚拟PC”软件&#xff0c;它使你可以在一台机器上同时运行二个或更多Windows、DOS、LINUX系统。 下载地址&#xff1a;https://customerconnect.vmware.com/en/downloads/#all_products 在搜索中…

用 Charles 断点调试 HTTPS 请求,原理解析

现在的网站基本都是 https 的&#xff0c;而 charles 是常用的 http 抓包工具&#xff0c;所以用 charles 调试 https 请求是常见的需求。 今天就分享下如何用 charles 调试 https 请求&#xff0c;如何打断点。 首先安装 charles&#xff0c;点击 start recording&#xff1…