热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

详解JS函数防抖

这篇文章主要介绍了详解JS中函数防抖的概念以及使用方法,文中代码十分详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下

一、什么是函数防抖

       概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。

       举个栗子,坐电梯的时候,如果电梯检测到有人进来(触发事件),就会多等待 10 秒,此时如果又有人进来(10秒之内重复触发事件),那么电梯就会再多等待 10 秒。在上述例子中,电梯在检测到有人进入 10 秒钟之后,才会关闭电梯门开始运行,因此,“函数防抖”的关键在于,在 一个事件 发生 一定时间 之后,才执行 特定动作

二、为什么需要函数防抖

  前端开发过程中,有一些事件,常见的例如,onresize,scroll,mousemove ,mousehover 等,会被频繁触发(短时间内多次触发),不做限制的话,有可能一秒之内执行几十次、几百次,如果在这些函数内部执行了其他函数,尤其是执行了操作 DOM 的函数(浏览器操作 DOM 是很耗费性能的),那不仅会浪费计算机资源,还会降低程序运行速度,甚至造成浏览器卡死、崩溃。这种问题显然是致命的。

       除此之外,短时间内重复的 ajax 调用不仅会造成数据关系的混乱,还会造成网络拥塞,增加服务器压力,显然这个问题也是需要解决的。

三、函数防抖如何解决上述问题

       根据上面对问题的分析,细细思索,可以想到如下解决方案。

       函数防抖的要点,是需要一个 setTimeout 来辅助实现,延迟运行需要执行的代码。如果方法多次触发,则把上次记录的延迟执行代码用 clearTimeout 清掉,重新开始计时。若计时期间事件没有被重新触发,等延迟时间计时完毕,则执行目标代码。

四、函数防抖的代码实现

       根据以上分析,我们对 “函数防抖” 来进行简单的代码实现,如下:

function debounce(fn,wait){
 var timer = null;
 return function(){
  if(timer !== null){
   clearTimeout(timer);
  }
  timer = setTimeout(fn,wait);
 }
}
 
function handle(){
 console.log(Math.random());
}
 
window.addEventListener("resize",debounce(handle,1000));

五、函数节流的使用场景

       函数防抖一般用在什么情况之下呢?一般用在,连续的事件只需触发一次回调的场合。具体有:

       搜索框搜索输入。只需用户最后一次输入完,再发送请求;

       用户名、手机号、邮箱输入验证;

       浏览器窗口大小改变后,只需窗口调整完后,再执行 resize 事件中的代码,防止重复渲染。

       目前遇到过的用处就是这些,理解了原理与实现思路,小伙伴可以把它运用在任何需要的场合,提高代码质量。

总结

       函数防抖其实是分为 “立即执行版” 和 “非立即执行版” 的,根据字面意思就可以发现他们的差别,所谓立即执行版就是 触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。 而 “非立即执行版” 指的是 触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。。

       在开发过程中,我们需要根据不同的场景来决定我们需要使用哪一个版本的防抖函数,一般来讲上述的防抖函数都能满足大部分的场景需求。但我们也可以将非立即执行版和立即执行版的防抖函数结合起来,实现最终的双剑合璧版本的防抖函数,以下为小伙伴们做了简单的实现:

/**
* @desc 函数防抖---“立即执行版本” 和 “非立即执行版本” 的组合版本
* @param func 需要执行的函数
* @param wait 延迟执行时间(毫秒)
* @param immediate---true 表立即执行,false 表非立即执行
**/
function debounce(func,wait,immediate) {
let timer;

return function () {
let cOntext= this;
let args = arguments;

if (timer) clearTimeout(timer);
if (immediate) {
var callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait)
if (callNow) func.apply(context, args)
} else {
timer = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
}

function handle(){
console.log(Math.random());
}

// window.addEventListener("mousemove",debounce(handle,1000,true)); // 调用立即执行版本
window.addEventListener("mousemove",debounce(handle,1000,false)); // 调用非立即执行版本

以上就是详解JS函数防抖的详细内容,更多关于JS函数防抖的资料请关注其它相关文章!


推荐阅读
  • 本文介绍了如何在 Framework7 中通过 AJAX 技术动态加载页面内容,确保用户在点击导航链接时能够顺利加载目标页面。 ... [详细]
  • 本文探讨了如何在JavaScript中调用PHP函数及实现两者之间的有效交互,包括通过AJAX请求、动态生成JavaScript代码等方法。 ... [详细]
  • 深入解析RAID0、RAID1和RAID5的不同特性及其安全性
    本文详细探讨了RAID0、RAID1和RAID5三种磁盘阵列技术的特点、优势以及它们在数据安全方面的表现。RAID0通过数据条带化提升性能,但牺牲了数据冗余;RAID1利用镜像技术确保数据的高可用性;而RAID5则结合了数据条带化和分布式奇偶校验,提供了较好的性能和数据保护。 ... [详细]
  • 本文介绍如何利用Python中的Epoll机制构建一个高效的Web服务器,该服务器能够处理多个并发连接,并向每个连接的客户端返回预定义的响应文本。通过使用Epoll,服务器可以实现高性能的I/O多路复用。 ... [详细]
  • 下面根据配置文件,来说明一些底层与webservices的关系:回顾一下servlet的映射模式。我们知道,servlet是从javax.servlet.http.HttpServ ... [详细]
  • 多版本CUDA共存与即时切换方案
    本文探讨了在同一台机器上安装并管理多个CUDA版本的方法,以适应不同软件或项目的需求。特别是在使用旧版PyTorch等依赖特定CUDA版本的软件时,该方法尤为实用。 ... [详细]
  • 本文介绍了一种解决方案,当笔记本电脑不具备作为无线接入点的能力时,如何通过开启Android手机的便携WLAN热点功能,使笔记本能够连接到手机并共享其网络资源,从而实现上网。文中详细描述了在Linux系统下配置的具体步骤。 ... [详细]
  • 本文介绍了如何通过安装 VirtualBox 和 Vagrant 来快速搭建和管理虚拟机环境。我们将详细探讨如何选择合适的 Box 镜像,以及如何高效地下载、添加和管理这些镜像。 ... [详细]
  • HTML中用于创建表单的标签是什么
    本文将详细介绍HTML中用于创建表单的标签及其基本用法,包括表单的主要特性和常用的属性设置。如果您正在学习HTML或需要了解如何在网页中添加表单,这将是一个很好的起点。 ... [详细]
  • Elasticsearch基础操作指南:使用Postman进行数据管理
    本文将介绍如何利用Postman工具执行基本的日志写入和数据管理操作。通过本教程,您将了解如何连接至Elasticsearch服务,创建索引,存储及检索数据。 ... [详细]
  • 本文详细介绍了在Oracle Data Guard中配置Standby Redo Log的方法,包括其重要性和具体的配置步骤。通过本文的学习,您将能够掌握如何有效地设置Standby Redo Log以提高数据保护和系统可用性。 ... [详细]
  • 本文详细介绍了如何利用Apple Pay的功能将门禁卡添加至iPhone或Apple Watch,适用于多种门禁系统,包括在线和离线模式。 ... [详细]
  • 本文详细记录了《PHP与MySQL Web开发》第一章的学习心得,特别关注了PHP的基本构成元素、标记风格、编程注意事项及表单处理技巧等内容。 ... [详细]
  • 应用程序配置详解
    本文介绍了配置文件的关键特性及其在不同场景下的应用,重点探讨了Machine.Config和Web.Config两种主要配置文件的用途和配置方法。文章还详细解释了如何利用XML格式的配置文件来调整应用程序的行为,包括自定义配置、错误处理、身份验证和授权设置。 ... [详细]
  • HPE DL380 Gen10 服务器从ESXi 6.0远程升级至ESXi 6.7
    本文介绍了如何通过HPE DL380 Gen10服务器的iLO5接口远程升级ESXi操作系统,从版本6.0升级到6.7。文中详细描述了远程登录、挂载镜像文件及执行升级的具体步骤。 ... [详细]
author-avatar
_路過蓅颩_
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有