前端常用算法(一):防抖+节流

news2024/9/28 1:16:56

目录

第一章 防抖

1.1 防抖(debounce)简介

1.2 应用场景

1.3 实现思路

1.4 手撕防抖代码

第二章 节流

2.1 节流(throttle)简介

2.2 应用场景

2.3 实现思路

2.4 手撕节流代码(方法:时间戳和计时器)

2.5 时间戳与计时器实现的区别

第三章 总结


第一章 防抖

1.1 防抖(debounce)简介

  • 场景:用户在一段时间频繁点击执行某个函数/事件,那么在这段时间,用户点击一次,计时器重新计时当在这段时间内用户没有触发该函数/事件时,该函数/事件会在这段时间结束时执行。
  • 应用示例理解:回城被打断,玩家残血准备回城,需要3s回城成功,但是在这个3s的过程中,玩家又重新点击了回城,导致3s回城重新计算,再等3s。

1.2 应用场景

  • 登录、发短信、发送post请求等按钮/事件避免用户点击太快,以致于发送了多次请求,需要防抖,最后一次发送请求即可;
  • 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖;
  • input输入框获取到value值不需要输入一个字符就获取一次,可以使用防抖,让其输入结束之后再获取其值
  • 文本编辑器实时保存,当无任何更改操作一秒后进行保存。
  • ……

1.3 实现思路

 

1.4 手撕防抖代码

function debounce(func,delay) {
    // 定义一个定时器timer
    let timer = null
    return function() {
        const that = this
        const args = arguments
        // 防抖核心:每次触发事件计时器都会重新计时
        clearTimeout(timer)
        timer = setTimeout(()=>{
            func.apply(that,args)
        },delay)
    }
}
  • 例子:

未调用防抖函数时:用户每在input输入/删除一个值,都会输出一个值;

    <input type="text" id="input">

    <script>
        let inputDom = document.getElementById('input')
        //获取输入框的输入内容
        inputDom.oninput = function(){
          console.log('this.value',this.value)
        }
    </script>

 

 

调用防抖函数后:用户在input输入/删除一个值delay之后才,会输出一个值

    let inputDom = document.getElementById('input')
    //func 是执行函数,delay 是事件执行的延迟时间,毫秒
    function debounce(func,delay) {
        // 定义一个定时器timer
        let timer = null
        return function() {
            const that = this
            const args = arguments
            // 防抖核心:每次触发事件计时器都会重新计时
            clearTimeout(timer)
            timer = setTimeout(()=>{
               func.apply(that,args)
            },delay)
        }
    }
    function handler() {
        console.log('this.value',this.value)
    }
    inputDom.addEventListener('input', debounce(handler, 1000))

第二章 节流

2.1 节流(throttle)简介

  • 场景:用户在一段时间频繁点击执行某个函数/事件,那么在这段时间,用户点击一次/多次(调用事件),都不会影响计时器执行,并且该函数/事件只执行一次。
  • 应用示例理解:技能冷却中,玩家在某种情况下使用了闪现这个技能,但是这个技能的冷却时间是120s,在这段时间里,玩家遇到危险,想要再使用闪现这个技能,频繁的点击它,但是并没用,闪现不会执行,计时器依然还在倒计时,等到120s倒计时为0才能再使用一次闪现的技能。

2.2 应用场景

  • 窗口调整
  • 页面滚动
  • 抢购和疯狂点击
  • 懒加载获取滚动条的位置
  • 鼠标连续不断地触发某事件(如点击),只在规定时间内触发一次
  • ……

2.3 实现思路

2.4 手撕节流代码(方法:时间戳和计时器)

// ---------------------节流1:使用时间戳---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle (func, delay) {
    //定义初始时间(开始触发事件的时间)
    let start = 0;
    return function () {
        const that = this
        const args = arguments
        // 获取当前时间戳
        let cur =Date.now()
        // 时间间隔大于延迟时间则进入
        if (cur - start >= delay) {
            //执行事件处理程序
            func.apply(that, args);
            //更新初始时间
            start = cur
        }
    }
}
// ---------------------节流2:使用定时器---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle(func, delay){
    // 自定义一个定时器
    var timer = null;
    return function(){
        var that = this;
        var args = arguments
        // timer为null表示可以发送请求了,否则还在请求中,不执行事件
        if(!timer){
            timer = setTimeout(function(){
                //执行事件处理程序
                func.call(that, args)
                //事件执行完后把定时器清除掉,下次触发事件的时候再设置
                timer = null;
            }, delay)
        }  
    }
}
  •  例子:

未调用节流函数时,每点击一次按钮,都会执行一次函数调用:

<button id="button1">发送了节流请求</button>
const button1Dom = document.getElementById('button1')
button1Dom.addEventListener('click',function(){
    console.log("节流:我发送了消息")
})

 使用节流函数之后,频繁的点击发送请求,它会在计时器结束之后再发,这段时间内点击发送一次请求之后,不会再发送请求:

const button1Dom = document.getElementById('button1')
// ---------------------节流1:使用时间戳---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle (func, delay) {
    //定义初始时间(开始触发事件的时间)
    let start = 0;
    return function () {
        const that = this
        const args = arguments
        // 获取当前时间戳
        let cur =Date.now()
        // 时间间隔大于延迟时间则进入
        if (cur - start >= delay) {
            //执行事件处理程序
            func.apply(that, args);
            //更新初始时间
            start = cur
        }
    }
}
// ---------------------节流2:使用定时器---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
// function throttle(func, delay){
//     // 自定义一个定时器
//     var timer = null;
//     return function(){
//         var that = this;
//         var args = arguments
//         // timer为null表示可以发送请求了,否则还在请求中,不执行事件
//         if(!timer){
//             timer = setTimeout(function(){
//                 //执行事件处理程序
//                 func.call(that, args)
//                 //事件执行完后把定时器清除掉,下次触发事件的时候再设置
//                 timer = null;
//             }, delay)
//         }  
//     }
// }
button1Dom.addEventListener('click',throttle(function(){
    console.log("节流:我发送了消息")
},1000))

频繁的点击,降低了发送的频率: 

 

2.5 时间戳与计时器实现的区别

最明显的区别就是在频繁点击的时候,会发现使用时间戳实现的节流会在调用的时候马上执行,而使用计时器实现会在时间段结束时执行

第三章 总结

  • 所谓防抖,就是指触发事件后,在 n 秒后函数才会执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间;节流,就是指连续触发事件,但是在 n 秒中只执行一次函数。
  • 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。

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

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

相关文章

【100天精通python】Day38:GUI界面编程_PyQT从入门到实战(中)

目录 专栏导读 4 数据库操作 4.1 连接数据库 4.2 执行 SQL 查询和更新&#xff1a; 4.3 使用模型和视图显示数据 5 多线程编程 5.1 多线程编程的概念和优势 5.2 在 PyQt 中使用多线程 5.3 处理多线程间的同步和通信问题 5.3.1 信号槽机制 5.3.2 线程安全的数据访问 Q…

高光谱 | 矿物识别和分类标签数据制作、农作物病虫害数据分类、土壤有机质含量回归与制图、木材含水量评估和制图

本课程提供一套基于Python编程工具的高光谱数据处理方法和应用案例。 本课程涵盖高光谱遥感的基础、方法和实践。基础篇以学员为中心&#xff0c;用通俗易懂的语言解释高光谱的基本概念和理论&#xff0c;旨在帮助学员深入理解科学原理。方法篇结合Python编程工具&#xff0c;…

企业如何为服务器找到合适的托管机房?

企业的服务器在业务经营中扮演着很重要的角色&#xff0c;提供可靠的数据存储和备份功能、计算能力和软件支持、网络通信连接等功能&#xff0c;是企业运行中关键的组成部分。因此&#xff0c;企业的服务器需要得到妥善的保管&#xff0c;为它们选择一个合适的托管机房十分有必…

TCP/IP---网络层

一、网络层的主要功能 1、提供了通讯过程中&#xff0c;必须要使用的另一个地址&#xff1a;逻辑IP地址【ipv4、ipv6】 2、连接不同媒介类型【内网--外网&#xff08;intra -- inter&#xff09;】 3、根据运行的不同的路由协议&#xff0c;选择不同的最佳路径 4、在选择的最好…

Chatgpt小程序源码java版实践

ChatGPT的技术和资源背景 ChatGPT是一种基于大数据的语言模型&#xff0c;通过对大量数据进行计算&#xff0c;例如语言出现的概率和适用环境等。ChatGPT所使用的语言模型参数大约有2000亿个。由于ChatGPT的计算运行需要大量的计算机资源&#xff0c;因此在工程上要实现它是非…

nginx代理文件目录、下载站点

文章目录 前言一、访问站点配置二、添加登录权限功能1.密码生成2.配置nignx 三、路径加 / 如何区分1、proxy_pass末尾有斜杠2、proxy_pass末尾无斜杠3、proxy_pass包含路径&#xff0c;且末尾有斜杠4、proxy_pass包含路径&#xff0c;末尾无斜杠 四、文件路径 alias与root区别总…

反转链表(单向链表)

声明 该系列文章仅仅展示个人的解题思路和分析过程&#xff0c;并非一定是优质题解&#xff0c;重要的是通过分析和解决问题能让我们逐渐熟练和成长&#xff0c;从新手到大佬离不开一个磨练的过程&#xff0c;加油&#xff01; 原题链接 反转链表备战技术面试&#xff1f;力…

搭建Web服务器并用cpolar发布至公网访问

本地电脑搭建Web服务器并用cpolar发布至公网访问 文章目录 本地电脑搭建Web服务器并用cpolar发布至公网访问前言1. 首先在电脑安装PHPStudy、WordPress、cpolar2. 安装cpolar&#xff0c;进入Web-UI界面3. 安装wordpress4. 进入wordpress网页安装程序5. 利用cpolar建立的内网穿…

【OpenGauss源码学习 —— 执行算子(hash join 算子)】

执行算子&#xff08;hash join 算子&#xff09; 连接算子hash join算子ExecInitHashJoin函数HashJoinState结构体TupleTableSlot 结构体JoinState结构体PlanState结构体ExecInitHashJoin函数部分代码介绍 ExecHashJoin函数调试信息 ExecEndHashJoin函数ExecReScanHashJoin函数…

Tween.js使用指南demo

案例&#xff1a; 小球的运动数字的自增 demo <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title&g…

网络连接(3次握手和4次挥手)

在进行3次握手和4次挥手传输数据时&#xff0c;都可能会出现丢包的情况&#xff0c;推荐看出现丢包问题的情况以及解决方法 一.为什么要进行3次握手&#xff1f; 在进行网络连接时&#xff0c;需要3次握手 3次握手的初心就是两方面&#xff1a; 1.投石问路&#xff0c;验证通…

df -h

df -h 命令用于查看磁盘占用的空间 Filesystem&#xff1a;表示该文件系统位于哪个分区&#xff0c;因此该列显示的是设备名称&#xff1b; Used&#xff1a;表示用掉的磁盘空间大小&#xff1b; Available&#xff1a;表示剩余的磁盘空间大小&#xff1b; Use%&#xff1a;磁盘…

国内小厂操刀,16G显存神卡只要599,老外急眼了

这年头&#xff0c;电脑配置 DIY 见怪不怪&#xff0c;你可曾听闻显卡规格 DIY&#xff1f; 前不久国外网友整出的 16G 显存 RTX 3070、国内大佬魔改的 22G 显存 RTX 2080Ti。 这些可都是官方从未发布过的船新版本。 显存容量无伤翻倍&#xff0c;关键还能不同批次搭配组合&a…

【严重】jeecg-boot/积木报表基于SSTI的任意代码执行漏洞

漏洞描述 JeecgBoot 是一款开源的的低代码开发平台&#xff0c;积木报表是其中的低代码报表组件。 JeecgBoot 受影响版本中由于积木报表 /jeecg-boot/jmreport/queryFieldBySql Api 接口未进行身份校验&#xff0c;使用 Freemarker 处理用户用户传入的 sql 参数&#xff0c;未…

微服务-Nacos(配置管理)

配置更改热更新 在Nacos中添加配置信息&#xff1a; 在弹出表单中填写配置信息&#xff1a; 配置获取的步骤如下&#xff1a; 1.引入Nacos的配置管理客户端依赖&#xff08;A、B服务&#xff09;&#xff1a; <!--nacos的配置管理依赖--><dependency><groupId&…

微服务-Nacos(注册中心)

Nacos是SpringCloud的一个功能非常强大的组件&#xff0c;想比eureka的功能更加丰富 官方的nacos简介 Nacos&#xff08;全称&#xff1a;Naming and Configuration Service&#xff09;是一个开源的动态服务发现、配置管理和服务管理平台。它由阿里巴巴集团开发并贡献给开源…

【高危】企业微信私有化2.5-2.6.93版本后台API未授权访问漏洞

漏洞描述 企业微信私有化2.5.x版本及2.6.930000版本以下后台中存在接口未授权访问漏洞&#xff0c;攻击者通过访问/cgi-bin/gateway/agentinfo接口可获得Secret&#xff0c;从而利用开放API获取企业通讯录等敏感信息及企业微信内应用权限。 漏洞名称企业微信私有化2.5-2.6.93…

案例20 基于Spring Boot+Redis实现学生信息按学号存储案例

1. 案例需求 基于Spring BootRedis实现学生信息按学号存储和取出功能&#xff0c;数据存储至Redis。 2. 创建Spring Boot项目 创建Spring Boot项目&#xff0c;项目名称为springboot-redis01。 3. 选择依赖 ​pom.xml文件内容如下所示&#xff1a; <?xml version"…

微信网页授权错误提示:redirect_uri 参数错误10003

如图网页授权域名也需要配置下&#xff0c;出现此问题是因为只配置了JS接口安全域名

即拼七人拼团模式:解决传统微商模式中的“人脉少”问题

许多各类企业都在为如何去引流用户、留存用户而烦恼&#xff0c;近期也有一些初创企业以及直销类型的朋友&#xff0c;咨询拼团对大众来说并不陌生&#xff0c;从多多的崛起开始&#xff0c;各种拼团活动就一直在我们的视野中浮现&#xff0c;对于这种算不上新颖&#xff0c;比…