不是哥们?你怎么抖成这样了?求你进来学学防抖吧!全方位深入剖析防抖的奥秘

前言

古有猴哥三打白骨精,白骨精 ======> 噶

今有用户疯狂点请求,服务器 ======> 噶

所以这防抖咱必须得学会!!!

本文就来讲解一下Web前端中防抖的奥秘吧!!!!

为什么要做防抖

在一些功能中,需要向服务器发送请求来获取数据。如果用户在短时间内疯狂的去点击触发这个功能,就会导致大量的请求被发送到服务器,造成资源浪费,同时也会使页面频繁刷新数据,降低用户的体验。

在这种情况下,使用防抖就显得非常重要了

防抖可以限制函数的执行频率,只在事件触发的间隔期之后执行一次

具有以下的效果:

  1. 提高页面性能: 减少不必要的函数调用,降低页面负载。
  2. 优化用户体验: 避免页面频繁刷新,让交互更加流畅。
  3. 减轻服务器压力: 减少无谓的网络请求,降低服务器的负担。

防抖代码详解

未防抖

首先我们分析以下的代码的执行结果是什么?

var btn = document.getElementById('btn');

btn.addEventListener('click', function(){
        console.log("提交")
    )
}

首先通过document.getElementById('btn') 方法获取了页面中 idbtn 的元素

使用 addEventListener 方法为该元素添加了一个点击事件监听。

当用户点击这个元素时,会执行console.log("提交") 输出字符串 "提交"

动画.gif

我们可以看到,由于按钮并没有做防抖处理,当我们疯狂点击提交按钮时,就会使得函数被疯狂的调用

这显然是不行的,哒咩哒咩!!!!!!

防抖

接下来我们开始去实现防抖效果了

首先分析一下防抖是一个怎么样的效果呢?

简单来说就是在规定的时间内没有下一次的触发,就执行函数

那么我们要怎么样去实现这个效果呢????

于是我们就想到了定时器触发执行函数,当我们在规定时间内没有触发,定时器就正常的去执行了函数,如果触发了,我们就把原先的定时器删了,创建一个新的定时器,这样我们不就实现了防抖,说干就干!

var btn = document.getElementById('btn');

function handle() {
    console.log('提交');
}
        
btn.addEventListener('click', debounce(handle))

//防抖函数
function debounce(fn) {
    let timer = null;
    //这是一个闭包
    return function () {
        //如果第二次的时间没到一秒就销毁上一次的计时器
        clearTimeout(timer)
        timer = setTimeout(fn, 1000)
    }
}

这段代码通过使用闭包和 setTimeout 的方式,实现了一个简单而实用的防抖功能。当用户在 1 秒内连续触发事件时,只有在 1 秒的间隔后才会执行一次 handle 函数,从而避免了不必要的重复操作。

如果还不是很了解什么是闭包的小伙伴可以先读一下这篇文章面试官:JavaScript执行机制中的闭包? - 掘金 (juejin.cn)

动画.gif

可以看到这段代码已经帮我们实现了防抖的效果了,但是这段代码是有不足之处的,我们继续讲解

这里我们会提到this的指向问题,对于不是很了解的小伙伴也可以先看看这篇文章了解一下this探索 JavaScript “this”指向的内在逻辑 - 掘金 (juejin.cn)

如果我们执行一下代码,结果是如何?

var btn = document.getElementById('btn');

function handle() {
    console.log(this);
}
btn.addEventListener('click', handle)

可以看到结果为btn

image.png

由于addEventListener决定handle的执行,所以addEventListener干扰了this,让this不指向全局

这里我们可以想到一个防抖函数肯定是不能说去改变了原有的this指向的

可是我们这里却改变了this的指向

var btn = document.getElementById('btn');

function handle() {
    console.log('提交', this);
}

btn.addEventListener('click', debounce(handle))

function debounce(fn) {
    let timer = null;
    return function () {
        clearTimeout(timer)
        timer = setTimeout(() => {  
            fn()
        }, 1000)
    }
}

可以看到this的指向变为了win

image.png

我们需要将指向修正回来

这里我们可以看到addEventListener决定执行的函数不再是handle而是我们的防抖函数debounce,所以很显然,debounce返回的函数里面的this才是我们想要的this,我们只需要将handle里的this指向debounce返回的函数里的this即可完成修正

var btn = document.getElementById('btn');

function handle(e) {
    console.log(this);
}

btn.addEventListener('click', debounce(handle))

function debounce(fn) {
    let timer = null;
    return function () {
        clearTimeout(timer)
        timer = setTimeout(() => {
            // this就是一个对象
            fn.call(this)
        }, 1000)
    }
}

此时handle的this就是正确的了

image.png

但是这里还有一个问题,addEventListener的回调函数会接收一个事件对象 e。这个事件对象包含了事件的相关信息,比如触发事件的元素、鼠标/键盘事件的坐标等

但是由于现在使用了防抖函数的原因,就使得e丢失了,在handle里面没有了e,而这个事件对象也在function里面,我们需要把他也传给handle

接下来修改代码

var btn = document.getElementById('btn');

function handle(e) {
    console.log(e);
    console.log(this);
}

btn.addEventListener('click', debounce(handle))

function debounce(fn) {
    let timer = null;
    return function (e) {
        clearTimeout(timer)
        timer = setTimeout(() => {
            fn.call(this, e)
        }, 1000)
    }
}

这样我们就实现了完整的防抖函数

image.png

总结

本文全方位深入剖析防抖的奥秘,通过结合代码以及其实现效果,由浅入深得讲解防抖的全部实现流程

希望能够帮助到你,如果对你有所帮助,别忘了一键三连,点赞、收藏加评论呦~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

适用于 Windows 11/10/8/7/Vista/XP 的最佳免费分区软件

无论您使用的是 SSD、机械磁盘还是任何类型的 RAID 阵列,硬盘驱动器都是 Windows 计算机中不可或缺的组件。在将文件保存到全新磁盘之前,您应该初始化它,创建分区并使用文件系统格式化。在运行计算机一段时间后,您需要收缩、扩展、…

14-25 剑和侠客 – 预训练模型三部曲2 – 视觉

概述 在第 1 部分中,我们讨论了适用于文本的预训练模型的重要性及其在当今世界的相关性。大型语言模型 (LLM),尤其是 GPT-3 和随后的 GPT-3.5,已经获得了极大的欢迎,从而在 AI 讨论中引起了越来越多的关注。我们已经看到了用于构…

everything高级搜索-cnblog

everything高级搜索用法 基础4选项验证 总结搜索方式 高级搜索搜指定路径文件名: 文件名 路径不含文件名: !文件名包含单词 路径包含指定内容: 路径 content:内容 大小写 区分大小写搜索搜指定路径文件名: case:文件名 路径全字匹配 全字搜指定路径文件名: wholewo…

网络安全基础-2

知识点 1.网站搭建前置知识 域名,子域名,DNS,HTTP/HTTPS,证书等 注册购买域名:阿里云企航_万网域名_商标注册_资质备案_软件著作权_网站建设-阿里云 2.web应用环境架构类 理解不同WEB应用组成角色功能架构: 开发语…

四、(1)网络爬虫入门及准备工作(爬虫及数据可视化)

四、(1)网络爬虫入门及准备工作(爬虫及数据可视化) 1,网络爬虫入门1.1 百度指数1.2 天眼查1.3 爬虫原理1.4 搜索引擎原理 2,准备工作2.1 分析爬取页面2.2 爬虫拿到的不仅是网页还是网页的源代码2.3 爬虫就是…

Golang | Leetcode Golang题解之第213题打家劫舍II

题目: 题解: func _rob(nums []int) int {first, second : nums[0], max(nums[0], nums[1])for _, v : range nums[2:] {first, second second, max(firstv, second)}return second }func rob(nums []int) int {n : len(nums)if n 1 {return nums[0]}…

7.pwn 工具安装和使用

关闭保护的方法 pie: -no-pie Canary:-fno-stack-protector aslr:查看:cat /proc/sys/kernel/randomize_va_space 2表示打开 关闭:echo 0>/proc/sys/kernel/randomize_va_space NX:-z execstack gdb使用以及插件安装 是GNU软件系统中的标准调试工具,此外GD…

【计组OS】I/O方式笔记总结

苏泽 “弃工从研”的路上很孤独,于是我记下了些许笔记相伴,希望能够帮助到大家 目录 IO方式:程序查询方式 工作原理 程序查询方式的详细流程: 1. 初始化阶段 2. 发送I/O命令 3. 循环检查状态 4. 数据传输 5. 继续查询 6…

reactor和proactor模型

Reactor模型是非阻塞的同步IO模型。在主线程中也就是IO处理单元中,只负责监听文件描述符上是否有事件发生,有的话就立即将事件通知工作线程,将socket可读可写事件放入请求队列,交给工作线程处理。 总而言之就是主线程监听有事件发…

期末考试结束,老师该如何私发成绩?

随着期末考试的落幕,校园里又恢复了往日的宁静。然而,对于老师们来说,这并不意味着工作的结束,相反,一系列繁琐的任务才刚刚开始。 成绩单的发放,就是其中一项让人头疼的工作。家长们焦急地等待着孩子的考试…

可视化作品集(08):能源电力领域

能源电力领域的可视化大屏,有着巨大的用武之地,不要小看它。 监控能源生产和消耗情况: 通过可视化大屏,可以实时监控能源生产和消耗情况,包括发电量、能源供应情况、能源消耗情况等,帮助管理者及时了解能…

14-39 剑和诗人13 - 顶级大模型测试分析和建议

​​​​​ 随着对高级语言功能的需求不断飙升,市场上涌现出大量语言模型,每种模型都拥有独特的优势和功能。然而,驾驭这个错综复杂的生态系统可能是一项艰巨的任务,开发人员和研究人员经常面临选择最适合其特定需求的模型的挑战。…

React中的useMemo和memo

引言 React是一个声明式的JavaScript库,用于构建用户界面。在开发过程中,性能优化是一个重要的方面。useMemo和memo是React提供的工具,用于帮助开发者避免不必要的渲染和计算,从而提升应用性能。 问题背景 在React应用中&#…

Golang | Leetcode Golang题解之第214题最短回文串

题目&#xff1a; 题解&#xff1a; func shortestPalindrome(s string) string {n : len(s)fail : make([]int, n)for i : 0; i < n; i {fail[i] -1}for i : 1; i < n; i {j : fail[i - 1]for j ! -1 && s[j 1] ! s[i] {j fail[j]}if s[j 1] s[i] {fail[i…

【密码学】密码学中的四种攻击方式和两种攻击手段

在密码学中&#xff0c;攻击方式通常指的是密码分析者试图破解加密信息或绕过安全机制的各种策略。根据密码分析者对明文、密文以及加密算法的知识程度&#xff0c;攻击可以分为以下四种基本类型&#xff1a; 一、四种攻击的定义 &#xff08;1&#xff09;唯密文攻击(COA, C…

MySQL学习(7):4种常用函数

1.字符串函数 mysql中内置了很多字符串函数&#xff0c;常用的几种如下&#xff1a; concat(s1,s2,s3...)字符串拼接&#xff0c;将s1,s2,s3...拼接成一个字符串 lower(s1) 将字符串s1全部转为小写upper(s1)将字符串s1全部转为大写lpad(s1,5,*) 如果字符串s1不足5位&#xff…

对BSV区块链的曼达拉网络通俗易懂的解释

​​发表时间&#xff1a;2023年6月15日 BSV区块链正在引入“曼达拉”升级&#xff0c;使BSV区块链网络的拓扑结构能够适配Teranode&#xff0c;适配这个可以大幅扩容的节点软件。BSV区块链上曼达拉网络的概念并不会改变整个系统的核心规则&#xff1b;相反&#xff0c;它能够引…

vue3使用方式汇总

1、引入iconfont阿里图库图标&#xff1a; 1.1 进入阿里图标网站&#xff1a; iconfont阿里&#xff1a;https://www.iconfont.cn/ 1.2 添加图标&#xff1a; 1.3 下载代码&#xff1a; 1.4 在vue3中配置代码&#xff1a; 将其代码复制到src/assets/fonts/目录下&#xff1…

Python打开Excel文档并读取数据

Python 版本 目前 Python 3 版本为主流版本&#xff0c;这里测试的版本是&#xff1a;Python 3.10.5。 常用库说明 Python 操作 Excel 的常用库有&#xff1a;xlrd、xlwt、xlutils、openpyxl、pandas。这里主要说明下 Excel 文档 .xls 格式和 .xlsx 格式的文档打开和读取。 …

python爬虫入门(三)之HTML网页结构

一、什么是HTML 1、网页的三大技术要素&#xff1a; HTML定义网页的结构和信息&#xff08;骨架血肉&#xff09;CSS定义网页的样式&#xff08;衣服&#xff09;JavaScript定义用户和网页的交互逻辑&#xff08;动作&#xff09; 2、一个最简单的HTML&#xff1a;用<>…