草庐IT

js实现防抖节流

dsyblog 2023-03-28 原文

前端项目开发过程中,对一个dom元素动作绑定了事件,但触发dom函数的动作过于频繁从而影响页面性能甚至出现bug的情况,比如:

页面滚动scroll事件、浏览器窗口resize事件、输入框搜索input事件等等,这些事件如果在一段时间内不加限制频繁触发必定会导致页面性能变差,尤其是绑定的事件内包含触发页面重绘重排、ajax请求这类操作时,甚至可能出现卡顿、假死、数值错误之类的bug。。。

所以为了防止绑定事件多次触发,就需要考虑使用防抖和节流的方案了

防抖:事件在指定时间间隔后触发,在时间间隔内如果重复触发事件就重新计时,多用于取多次操作的最后一次操作为有效操作的场景如:搜索框输入搜索、点击切换状态按钮、表单数据提交

节流:事件在指定事件间隔内只触发一次,时间间隔内重复触发则只有第一次生效,超出时间间隔直接执行,多用于多次操作会取得相同结果从而避免多次触发的情况如:滚动加载、新增列表项、拖拽元素

防抖和节流在代码中如何实现:

防抖

 1 /**
 2  * @param {*} fn 要进行防抖的函数
 3  * @param {*} delay 延迟几秒执行
 4  * @param {*} immediate 是否立即执行一次防抖函数(fn)
 5  */
 6 function debounce(fn, delay, immediate) {
 7   let timeout = null
 8   return function(...args) {
 9     // 清除已存在定时任务
10     if(timeout) {
11       clearTimeout(timeout)
12       timeout = null
13     } else {
14       if(immediate) fn.apply(this, args)
15     }
16     // 重新设置定时任务
17     timeout = setTimeout(() => {
18       fn.apply(this, ...args)
19     }, delay)
20   }
21 }

节流

 1 /**
 2  * 立即执行版本
 3  * @param {*} fn 要执行节流的函数
 4  * @param {*} wait 节流函数执行周期
 5  */
 6 function throttle(fn, wait) {
 7   let pre = Date.now()
 8   return function(...args) {
 9     let now = Date.now()
10     if(now - pre > wait) {
11       fn.apply(this, args)
12       pre = now
13     }
14   }
15 }
16 
17 /**
18  * 延迟指定时间执行版本
19  * @param {*} fn 要执行节流的函数
20  * @param {*} wait 节流函数执行周期 
21  */
22 function throttle(fn, wait) {
23   let timeout = null
24   return function(...args) {
25     if(!timeout) {
26       setTimeout(() => {
27         fn.apply(this, args)
28         timeout = null
29       }, wait)
30     }
31   }
32 }

 最后我们来看一下使用了防抖和节流后的效果:

防抖:

这里通过在控制台输出input框内容模拟实际应用场景中用户手动输入搜索,可以看到没有使用防抖函数,用户每次输入都会触发搜索操作,非常损耗性能

使用防抖后(这里的防抖延迟我设定的是1s),可以看到只有当用户输入间隔超过1s后才会真正执行搜索逻辑,大大节省了性能

节流:

通过页面滚动条滚动到指定高度时触发控制台输出不同内容模拟滚动加载,可以看到在不使用节流的情况下,滚动条滚动到指定高度后继续滚动还会触发加载函数

 

而使用了节流后,即使多次滚动也只会触发一次加载函数,大大节省了性能

 

有关js实现防抖节流的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  3. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  4. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  5. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  6. ruby - Arrays Sets 和 SortedSets 在 Ruby 中是如何实现的 - 2

    通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复

  7. ruby - "public/protected/private"方法是如何实现的,我该如何模拟它? - 2

    在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定

  8. ruby - 实现k最近邻需要哪些数据? - 2

    我目前有一个reddit克隆类型的网站。我正在尝试根据我的用户之前喜欢的帖子推荐帖子。看起来K最近邻或k均值是执行此操作的最佳方法。我似乎无法理解如何实际实现它。我看过一些数学公式(例如k表示维基百科页面),但它们对我来说并没有真正意义。有人可以推荐一些伪代码,或者可以查看的地方,以便我更好地了解如何执行此操作吗? 最佳答案 K最近邻(又名KNN)是一种分类算法。基本上,您采用包含N个项目的训练组并对它们进行分类。如何对它们进行分类完全取决于您的数据,以及您认为该数据的重要分类特征是什么。在您的示例中,这可能是帖子类别、谁发布了该项

  9. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  10. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

    rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

随机推荐