【JS进阶】防抖与节流
防抖与节流
1.防抖
1.1 为什么要防抖?
在项目中,有的操作是高频触发的,但是其实触发一次就好了,比如我们短时间内多次缩放页面,那么我们不应该每次缩放都去执行操作,应该只做一次就好。再比如说监听输入框的输入,不应该每次都去触发监听,应该是用户完成一段输入后再进行触发。
所以,防抖就是防止抖动,避免事件的重复触发。
思路:等待用户高频操作完成后,再完成操作。
1.2 基础防抖如何实现?
基础设计思路:事件触发后,开启一个定时器,当该定时器到时间时,触发操作;而如果事件在该定时器限定的时间内再次触发,则清除当前定时器,并再次开启一个新的定时器。
代码如下:
// fn --- 要执行的操作,delay --- 延迟时间,在该时间内用户没有再次触发则执行操作
function debounce(fn, delay){// timer --- 定时器的名称,用于清除定时器let timer = null;return function(arguments){// 实际进行防抖的部分// 如果再次触发,首先清除上一次的定时器clearTimeout(timer);// 创建一个新定时器并记录名称timer = setTimeout(()=> {// 用apply方法执行目标函数fn.apply(this, arguments);}, delay)}
}
实际上,可以通过下面这张图来理解基础的防抖:
2.节流
2.1 为什么要节流?
基础的防抖存在一个问题,事件会一直等到用户完成操作后一段时间在操作,如果一直操作,会一直不触发。比如说是一个按钮,点击就发送请求,如果一直点,那么请求就会一直发布出去。这里正确的思路应该是第一次点击就发送,然后上一个请求回来后,才能再发,即节流。
节流就是减少流量,将频繁触发的事件减少,并每隔一段时间执行。即,控制事件触发的频率。
思路:某个操作希望上一次的完成后再进行下一次,或者希望隔一段时间触发一次
2.2 如何实现基础节流?
基础设计思路:我们可以设计一种类似控制阀门一样定期开放的函数,事件触发时让函数执行一次,然后关闭这个阀门,过了一段时间后再将这个阀门打开,再次触发事件。
代码如下:
// fn --- 要执行的操作,delay --- 延迟时间,在该时间内操作最多只会执行一次
function throttle(fn, delay){// 阀门是否开启let valid = true;return function(arguments){if(valid) { //如果阀门已经打开,就继续往下,设定定时器,指明在一定延迟时间后执行一次操作// 此时已经确定会执行一次操作,因此关闭阀门valid = false;setTimeout(()=> {fn.apply(this, arguments);//定时器结束后执行valid = true;//执行完成后打开阀门}, delay)}}
}
实际上,可以通过下面这张图来理解基础的节流:
3.防抖节流的应用场景、联系以及区别
防抖
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源
- window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
节流
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多
联系与区别
防抖节流的共同点在于:都是为了阻止操作高频触发,从而浪费性能。
两者的不同点在于:
- 防抖是触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计时。适用于可以多次触发但触发只生效最后一次的场景,可能会出现操作始终不执行的情况。
- 而节流则不同,事件高频触发,无论触发多少次,在一定时间内只会执行一次,即定期执行。相比于防抖,节流的响应更加平滑,不会出现始终不执行操作的情况!
4.防抖与节流的优化
对于上面的基础防抖与节流的方法,主要有两个可以优化的方面:
- 复用性优化:对于实际项目中,我们不可能在每次需要进行防抖节流的时候,都重新写一遍代码,因此,我们需要将防抖节流的方法封装为内部API提高复用性!
- 功能方面的优化:
- 防抖:添加立即执行选项解决可能始终不执行的问题;延迟防抖,解决高频设定定时器的问题。
- 节流:可能需要点击后立即执行等等。
立即执行
在某些业务场景中,使用防抖节流时,基础的防抖节流可能会导致响应时间变长,这就会影响到用户的使用体验,因此,需要在触发事件的时候,立即执行处理函数,但后续也能起到防抖节流的作用。
立即执行的防抖和节流,其原理是一致的,即:添加一个计数器或立即执行的标识。
实现如下:
// 防抖
export const debounce = (fun , wait=1000) => {let timeout = nulllet count = 0return function(){let _this = thislet arg = argumentsif(timeout){//如果存在定时器就清空clearTimeout(timeout)}if (!count) {// 第一次点击时立即执行count++fun.apply(_this, arg)timeout = setTimeout(() => {count = 0}, wait)} else {count++timeout = setTimeout(() => {fun.apply(_this, arg)count = 0}, wait)}}
}// 节流
export const throttled = (fun, wait=1000, immediate) => {let preTime = 0;let timerId;return function() {let _this = this;let args = arguments;if(immediate) { // immediate 为true 时立即执行let nowTime = Date.now();if(nowTime - preTime > wait) {fun.apply(_this, args);preTime = nowTime;}} else {if(!timerId) {timerId = setTimeout(function() {fun.apply(_this, args);timerId = null;}, wait);}}}
}
其他优化
在不同的业务场景中,对于防抖节流也有不同的需求,如果单纯地为了每一个场景编写防抖节流函数,是相当费事且麻烦的工作,因此,不如使用别人封装好的库。
参考:http://t.csdn.cn/RVzMK
最终解决方案:
underscore.js 库中的 _.throttle()
和 _.debounce()
— 参考https://www.likecs.com/show-307738657.html
相关文章:

【JS进阶】防抖与节流
防抖与节流 1.防抖 1.1 为什么要防抖? 在项目中,有的操作是高频触发的,但是其实触发一次就好了,比如我们短时间内多次缩放页面,那么我们不应该每次缩放都去执行操作,应该只做一次就好。再比如说监听输入…...

【css】linear-gradient()的用法
linear-gradient() CSS函数创建一个由两种或多种颜色沿一条直线进行线性过渡的图像,其结果是<gradient>数据类型的对象,此对象是一种特殊的<image> 数据类型。 语法 /* 渐变轴为 45 度,从蓝色渐变到红色 */ linear-gradient(45deg, blue, red);/* 从右…...

java: 读取snakeyaml-1.26.jar各种jar包时出错; error in opening zip file
可能的问题 jar有问题idea没有权限等等其他问题。但执行后报错就是读取不了,还报error in opening zip file这个错。 解决问题 我的错就是jar包有问题。我先后进行了很多次把jar包位置里的东西全部删除,然后重新maven下载但是不管用。最后从网站上下载…...

医疗知识图谱 neo4j
开源项目: https://github.com/liuhuanyong/QASystemOnMedicalKG 一.效果 二.需要安装: pip install pyahocorasick pip install py2neo 三.需要修改: 需要改的点: 1.改连接的方式 2.改读文件的方式 MedicalGraph 运行&am…...

【LeetCode-简单题】367. 有效的完全平方数
文章目录 题目方法一:二分查找 题目 方法一:二分查找 找 1 - num 之间的 mid, 开方是整数 就找得到 mid, 不是整数自然找不到mid class Solution { // 二分查找 ;找 1 - num 之间的mid 开方是整数 就找得到 不是…...
vben-admin中渲染table表格时怎么处理不同的数据结构
最近在用vben admin开发后台管理系统,vben admin这个后管端框架封装的非常细,颗粒度非常细,如果了解里面的组件或者api用法,那开发起来非常快。如果不了解,那就非常痛苦了,目前关于vben admin这块的开发问题…...

从零开始在树莓派上搭建WordPress博客网站并实现公网访问
文章目录 序幕概述1. 安装 PHP2. 安装MySQL数据库3. 安装 Wordpress4. 设置您的 WordPress 数据库设置 MySQL/MariaDB创建 WordPress 数据库 5. WordPress configuration6. 将WordPress站点发布到公网安装相对URL插件修改config.php配置 7. 支持好友链接样式8. 定制主题 序幕 …...
Go基础18-理解方法的本质以选择正确的receiver类型
Go语言虽然不支持经典的面向对象语法元素,比如类、对象、继承等,但Go语言也有方法。和函数相比,Go语言中的方法在声明形式上仅仅多了一个参数,Go称之为receiver参数。receiver参数是方法与类型之间的纽带。 Go方法的一般声明形式…...
Go基础12-理解Go语言表达式的求值顺序
Go语言在变量声明、初始化以及赋值语句上相比其先祖C语言做了一些改进,诸如: ● 支持在同一行声明和初始化多个变量(不同类型也可以) var a, b, c 5, "hello", 3.45 a, b, c : 5, "hello", 3.45 // 短变量…...

OJ练习第165题——修车的最少时间
修车的最少时间 力扣链接:2594. 修车的最少时间 题目描述 给你一个整数数组 ranks ,表示一些机械工的 能力值 。ranksi 是第 i 位机械工的能力值。能力值为 r 的机械工可以在 r * n2 分钟内修好 n 辆车。 同时给你一个整数 cars ,表示总…...

纯前端实现 导入 与 导出 Excel
最近经常在做 不规则Excel的导入,或者一些普通Excel的导出,当前以上说的都是纯前端来实现;下面我们来聊聊经常用到的Excel导出与导入的实现方案,本文实现技术栈以 Vue2 JS 为例 导入分类: 调用 API 完全由后端来解析数…...
关于一次两段式提交和数据库恢复数据我的一些想法
binlog是服务层的功能,而redolog是innodb引擎的功能,binlog主要用于主从复制,redolog主要用做数据的恢复,我们必须保证binlog和redolog日志数据的一致性。恢复数据时也必须遵守此一致性。 1.如果只写一次redolog会出现什么问题&a…...
阿里巴巴springcloud的gateway网关如何用继承接口WebExceptionHandler定义一个json格式的404错误页面实例
如果你想通过实现 WebExceptionHandler 接口来定义一个返回 JSON 格式的 404 错误页面的实例,可以按照以下方式操作: import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.ster…...
『力扣每日一题07』字符串最后一个单词的长度
气死我啦,今天这道题花了快一个小时,我学完了答案的解法,放上去在线 OJ ,一直报错,找来找去都找不到自己错在哪,明明跟答案一模一样。后来还是学了另一种解法,才跑出来的(̥̥̥̥̥̥̥̥o̥̥…...

成都睿趣科技:抖音开店初期要注意什么
随着社交媒体和短视频平台的崛起,抖音已经成为了一个风靡全球的短视频应用,拥有着庞大的用户群体。因此,越来越多的创业者开始在抖音上开设自己的线上店铺,希望借助这个平台赚取丰厚的利润。然而,在抖音开店初期&#…...
QT 5.13保姆级安装教程
辨清关系 要想学习一个新的东西,我们必须知其事,达其理,悟其道,然后才能无往而不利也! 我们常听到QT、Qt Creator 和 Qt SDK ,这三者究竟是什么,他们之间的关系又是如何的?在安装QT之前我们先来了解一下他们之间的关系: Qt:Qt 是一个跨平台的 C++ 应用程序开发框架,…...
js 创建DOM,并添加父DOM上,移除某个DOM的所有子节点
在sectionIdDiv上,添加子DOM <div ref"sectionIdDiv" class"sectionIdDiv"> </div>创建你要添加的子DOM ## 创建DOM let elementDom document.createElement(div)## 设置DOM的样式 elementDom.style.height "15px" e…...

element el-input 二次封装
说明:为实现输入限制,不可输入空格,长度限制。 inputView.vue <template><!-- 输入框 --><el-input:type"type":placeholder"placeholder"v-model"input"input"inputChange":maxle…...

[源码系列:手写spring] IOC第十三节:Bean作用域,增加prototype的支持
为了帮助大家更深入的理解bean的作用域,特意将BeanDefinition的双例支持留到本章节中,创建Bean,相关Reader读取等逻辑都有所改动。 内容介绍 在Spring中,Bean的作用域(Scope)定义了Bean的生命周期和可见性。包括单例和…...
【性能优化】事件委托
一、为什么要用事件委托 当 dom 有事件处理程序时,我们一般都会直接给它设置事件处理程序,设想一下,如果在一个父元素中有很多个 dom 需要添加事件处理呢?比如 ul 中处在100个 li,每个 li 都有相同的 click 事件&…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...