首页 > 其他分享 >防抖和节流及多种实现方式

防抖和节流及多种实现方式

时间:2023-04-24 10:25:48浏览次数:33  
标签:function 多种 防抖 函数 触发 timer 节流

当用户在网页中进行操作时,如点击、滚动、输入等,往往会频繁地触发事件。如果每个事件都立即执行相应的函数,可能会导致性能问题和用户体验不佳,因为这些函数可能需要执行复杂的操作,如计算、网络请求等。

为了优化这种情况,我们可以使用防抖和节流来限制函数的调用次数,从而提高性能和用户体验。

 


防抖

防抖是指在一定的时间间隔内,将多次触发的事件合并成一次执行。

防抖的实现思路是:每次事件被触发时,设置一个计时器,在指定的时间间隔内,如果该事件被再次触发,则清除计时器并重新开始计时,直到指定的时间间隔内没有事件触发为止,然后调用函数。

 

防抖可以用于处理一些频繁触发的事件,如窗口大小改变、输入框输入等。以下是一个简单的防抖函数实现:

function debounce(fn, delay) {
  let timer;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  };
}

 

这个函数接收两个参数: fn 是要防抖的函数, delay 是防抖时间间隔。返回一个新的函数,在防抖时间间隔内,重复调用这个新函数不会立即触发原函数,只有等时间间隔过去之后才会触发。

 



节流

节流是指在一定的时间间隔内,函数只被调用一次。如果在这个时间间隔内触发了多次事件,只有第一次会调用函数,其余的会被忽略。

节流的实现思路是:每次事件被触发时,如果函数没有在指定的时间间隔内被调用过,则调用函数并设置一个计时器,在指定的时间间隔内不再触发事件。如果在指定的时间间隔内再次触发了事件,则不调用函数,直到指定的时间间隔过去,重新开始调用函数。

 

节流可以用于处理一些频繁触发的事件,如页面滚动、鼠标移动等。以下是一个简单的节流函数实现:

function throttle(fn, delay) {
  let timer;
  return function() {
    const context = this;
    const args = arguments;
    if (!timer) {
      timer = setTimeout(function() {
        fn.apply(context, args);
        timer = null;
      }, delay);
    }
  };
}

这个函数接收两个参数: fn 是要节流的函数, delay 是节流时间间隔。返回一个新的函数,在指定的时间间隔内,只能调用一次原函数。

 

 

防抖和节流的实现方式可以有多种,具体实现应该根据实际场景进行调整。下面介绍一些常见的实现方式。

 


立即执行版和非立即执行版

防抖和节流的实现中,可以根据需求选择立即执行版或非立即执行版。

立即执行版是指在每次触发事件时,立即执行一次函数,然后在指定的时间间隔内不再执行。这种方式适合处理一些需要立即响应的事件,如按钮点击等。

 

以下是立即执行版的防抖函数实现:

function debounce(fn, delay, immediate) {
  let timer;
  return function() {
    const context = this;
    const args = arguments;
    if (immediate && !timer) {
      fn.apply(context, args);
    }
    clearTimeout(timer);
    timer = setTimeout(function() {
      if (!immediate) {
        fn.apply(context, args);
      }
      timer = null;
    }, delay);
  };
}

 

这个函数增加了一个参数 immediate ,用来指定是否立即执行函数。如果设置为 true ,则在触发事件时立即执行函数;否则等待指定的时间间隔后再执行。

 

 

非立即执行版是指在事件停止触发指定时间后才执行一次函数。这种方式适合处理一些连续触发的事件,如输入框输入等。

以下是非立即执行版的防抖函数实现:

function debounce(fn, delay, immediate) {
  let timer;
  return function() {
    const context = this;
    const args = arguments;
    if (timer) {
      clearTimeout(timer);
    }
    if (immediate && !timer) {
      fn.apply(context, args);
    }
    timer = setTimeout(function() {
      if (!immediate) {
        fn.apply(context, args);
      }
      timer = null;
    }, delay);
  };
}

这个函数与立即执行版的实现相似,区别在于多了一个 if (timer) { clearTimeout(timer); } 判断。如果计时器已经存在,则在重新设置计时器之前先清除之前的计时器。

 


时间戳版和定时器版

防抖和节流的实现中,可以根据需求选择时间戳版或定时器版。

时间戳版是指在事件触发后,记录下当前的时间戳,并在下次事件触发时再次记录时间戳。在指定的时间间隔内,如果事件再次触发,则更新时间戳。如果时间戳与当前时间的差值超过了指定的时间间隔,则执行函数。这种方式适合处理一些需要立即响应的事件,如按钮点击等。

 

以下是时间戳版的节流函数实现:

function throttle(fn, delay) {
  let last = 0;
  return function() {
    const context = this;
    const args = arguments;
    const now = +new Date();
    if (now - last > delay) {
      fn.apply(context, args);
      last = now;
    }
  };

这个函数中, last 记录上次执行函数的时间戳,每次事件触发时,计算当前时间戳与上次执行函数的时间戳的差值,如果超过指定的时间间隔,则执行函数并更新 last 。

 

 


定时器版是指在事件触发后,设置一个定时器,在指定的时间间隔内不再触发事件。如果在指定的时间间隔内再次触发了事件,则不执行函数,直到定时器到期后再次执行函数。这种方式适合处理一些连续触发的事件,如页面滚动、鼠标移动等。

 

以下是定时器版的节流函数实现:

function throttle(fn, delay) {
  let timer;
  return function() {
    const context = this;
    const args = arguments;
    if (!timer) {
      timer = setTimeout(function() {
        fn.apply(context, args);
        timer = null;
      }, delay);
    }
  };
}

这个函数与之前介绍的非立即执行版的防抖函数实现类似,区别在于将 setTimeout 的时间间隔设置为指定的时间间隔,而不是事件触发后的延迟时间。


防抖和节流的主要区别在于它们限制函数调用的方式不同。防抖是指在指定的时间间隔内将多次触发的事件合并成一次执行,而节流是指在指定的时间间隔内,函数只被调用一次。同时,防抖和节流也有一些缺点,比如可能会导致事件响应延迟或事件被忽略等问题。因此,在实际使用中,需要根据场景进行权衡和选择。

 

标签:function,多种,防抖,函数,触发,timer,节流
From: https://www.cnblogs.com/ronaldo9ph/p/17348583.html

相关文章

  • js实现防抖(debounce)与节流(throttle)
    防抖(debounce)一句话概括:防抖是给定一个时间周期,如果触发事件的周期小于该事件(也就是触发过快),则不会触发事件。举个例子:我给定的时间周期是1s,如果我在触发第一次事件后1s内触发该事件,则重新开始计时,直到触发周期大于1s才会执行事件的方法。functiondebounce(fn,timeout){......
  • js-防抖和节流的区别及实现
    函数防抖(debounce):触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。函数节流(throttle):高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。函数节流(throttle)与函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过......
  • 记录一次艰难的云服务器部署前后端项目springBoot+mybatis和vue(两天解决的前后端跨域
    前言大家好我是歌谣今天继续给大家带来后端java的学习最近刚学习完java的一个增删改查紧接着就是部署项目了代码准备工作前端:vue后端:springboot+mybatis数据库mysql部署后端项目打包找到maven-package-runmavenbuild云服务器上面建立文件mkdir/www/springBoot创建文件......
  • TCP连接状态的多种判断方法
    ​前言在TCP网络编程模型中,无论是客户端还是服务端,在网络编程的过程中都需要判断连接的对方网络状态是否正常。在linux系统中,有很多种方式可以判断连接的对方网络是否已经断开。通过错误码和信号判断通过select系统函数判断通过TCP_INFO套接字选项判断通过SO_KEEPALIVE套接......
  • CH224单芯片集成USB PD等多种快充协议
    CH224单芯片集成PD3.0/2.0,BC1.2等升压快充协议,内置PD通讯模块,高集成度,外围精简。支持输出电压检测功能,并且提供过温、过压保护等。可广泛应用于各类电子设备拓展高功率输入,如无线充电器、电动牙刷、锂电池电动工具等各类应用场合。2、功能特点l l l l l支持5V至15V输入电压支持......
  • 怎么批量修改文件名称,支持多种导入文件素材的方式
    文件太多,如何快速重命名呢?重命名之前,又该如何导入文件素材呢?今天小编给大家分享一个新的处理技巧,下面一起来试试吧。需要哪些工具?安装一个文件批量改名高手文件素材若干怎么快速操作?步骤1:打开【文件批量改名高手】,在“文件批量重命名”中,支持多种导入文件的方式步骤2:第一种是单击“......
  • 【故障诊断】基于KNN、SVM、RF、DT、ET多种算法实现制冷系统故障诊断附Matlab代码
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • AGC002D Stamp Rally 多种做法 kruskal重构树/可持久化并查集/整体二分
    D-StampRally(atcoder.jp)这题做法很多,我写的是可持久化并查集做法,但是裸的可持久化并查集是$O(nlog^3n)$,能过但是很慢!看洛谷的题解有一位大佬写了一个很妙的并查集的写法,按秩合并,每一步合并时用vector记录一下这个被合并到的节点的size和当前的时间,这样做可以找到每一个时......
  • 自主阅读笔记04《多种软件体系结构风格的分析与比较》
    文章来源《计算机与数字工程》作者:刘凯′梁欣?李欣宜’张俊萍赵丽娜软件体系结构的基本概念软件体系结构是从一个较高抽象层次来考虑组成系统的构件、构件之间的交互,以及由构件与构件交互形成的拓扑结构的关系。这些要素应该满足一定的限制,遵循一定的设计规则,能够在一定的环......
  • 传输数据稳如老狗,还支持多种接口,这款DTU让智能化更简单
    如果你的项目正在向着智慧化转变或发展,那么你一定会深刻意识到数据传输的稳定性对于整个系统的稳定运行的重要性。毕竟,项目的智能化发展需要时刻保持数据的可靠性和稳定传输,如果一旦传输因设备或者网络等因素导致中断,那么将会造成不可估量的损失。因此一款极为稳定可靠的通信产品......