JavaScript中的防抖与节流-图文版
01、防抖还是节流
防抖 与 节流 目的都是避免一定时间内,大量重复的操作造成的性能损耗。因此原理也类似,都是阻止过多的事件执行,只保留一部分来执行。适用场景略有不同,也有交叉,动手练习一遍就懂了。
区别 | 防抖(Debounce) | 节流(throttle) |
---|---|---|
描述 | 一定延迟时间内,连续事件只执行最后一次 | 一段固定时间内只执行一次 |
原理 | 只保留一个延时setTimeout() 的执行器,后续新的替代旧的 |
判断时间间隔,在固定间隔时间内,只执行一次。 |
执行次数 | 只执行最后一次 | 执行首次、最后一次,或首次+最后一次 |
合适场景 | 连续操作只需要一次的,如变更内容提交到后端 | 连续操作定期执行的场景:连续的UI交互,如拖拽、滚动 |
02、什么是防抖(Debounce)?
按字面意思理解就是 防止抖动(Debounce /di'bauns/ 防抖动),本来只需要点击一次,结果手抖操作了很多次,重复执行就造成了额外的浪费。
防抖函数的原理:在一定延迟时间内,连续触发的事件合并只执行 最后 一次。技术原理是用闭包保存一个延时执行函数setTimeout(func, delayTime)
返回变量,只要延迟时间delayTime
内新触发的执行器,就会代替旧执行器。
实现代码:
/****************************** 防抖函数 ******************************/
//参数func:需要防抖的函数
//参数delayTime:延时时长,单位ms
function debounce(func, delayTime) {
//用闭包路缓存延时器id
let timer;
return function (...args) {
if (timer)
clearTimeout(timer); //清除-替换,把前浪拍死在沙滩上
timer = setTimeout(() => {
func.apply(this, args);
}, delayTime);
}
}
适用场景:
- 提交按钮,避免重复点击提交数据,只执行最后一次。
- 文本框输入的响应:如基于输入文本服务端联想查询,对输入内容的服务端验证等,防抖就可以避免没必要的请求,节约资源。
- 连续触发的事件,如窗口的
resize
事件、窗口的滚动scroll
事件,只处理最后一次。
使用案例:滚动浏览器滚动条到末尾。
- 如果不用防抖函数,
scroll
事件频繁触发,共触发了29次。 - 加上防抖函数,同样的速度移动,只触发了最后一次。
//移动浏览器滚动条到末尾,无防抖
window.addEventListener('scroll', print); //执行了29次
//加上防抖,延迟300ms
window.addEventListener('scroll', debounce(print, 300)); //执行了1次
let index = 0;
function print() {
console.log(index++);
}
03、为何要节流(throttle)?
节流(throttle)字面意思就是节约流量(throttle /ˈθrɑːtl/ 节流阀),一个小朋友一分钟只能吃一勺饭,每分钟喂了30勺,喂得太快要么食物浪费了,要么被噎到。
节流函数的原理:一定时间内只执行一次事件,在一段时间intervalTime
内,不管触发了多少次事件(大于1)都只执行一次。
- 因此首先需要判断间隔时间,是否在间隔时间内。
- 具体执行的时机,可选择首次,也可以选择最后一次,或者首次+最后一次。
实现代码:三种实现方式
- 实现1:单位时间内执行第一次(立即执行),节流后面的,基于时间间隔判断。
- 实现2:单位时间内执行第一次(延迟执行),节流后面的,基于延时函数
setTimeout()
。 - 实现3:执行首次+最后一次,节流中间的,比较综合全面的的实现方式!
// 实现1:单位时间内执行第一次(立即执行),节流后面的
function throttle(func, intervalTime = 100) {
let lastTime = 0;
return (...args) => {
let now = Date.now();
//首次调用会执行
if (now - intervalTime > lastTime) {
func.apply(this, args);
lastTime = now;
}
}
}
// 实现2:单位时间内执行第一次(延迟执行),节流后面的
const throttle2 = (func, intervalTime = 100) => {
// 定义falg,初试为true
let flag = true;
// 返回的函数是每次用户实际调用的节流函数
return (...args) => {
const ctx = this;
// 如果flag为true,则执行定时器
if (flag) {
setTimeout(() => {
func.apply(ctx, args);
// 函数执行完毕后=true;
flag = true;
}, intervalTime);
}
//没执行完成前都为false
flag = false;
};
}
// 实现3:执行首次+最后一次,节流中间的,比较综合的节流方式!
function throttleMiddle(func, intervalTime = 100) {
let timer = null;
let startTime = 0;
return (...args) => {
const ctx = this;
const now = Date.now();
if (startTime && now < startTime + intervalTime) {
//替换前面的
clearTimeout(timer);
timer = setTimeout(() => {
startTime = now;
func.apply(ctx, args);
}, Math.max(intervalTime - (Date.now() - startTime), 0)); //剩余等候时间
} else { //每轮首次会执行,立即执行
startTime = now;
func.apply(ctx, args);
}
}
}
// 节流-函数扩展,使用的throttleMiddle版本
Function.prototype.throttle = function (intervalTime = 100) {
let func = this;
let startTime, timer = null;
//这里不能用箭头函数,会导致this污染
return function (...args) {
const ctx = this;
let now = Date.now();
if (startTime && now < startTime + intervalTime) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
startTime = now;
}, Math.max(intervalTime - (now - startTime), 0));
}
else {
startTime = now;
func.apply(ctx, args);
}
}
}
适用场景:
- 定时秒杀、抽奖按钮,运行多次提交,避免太过频繁的提交把服务端搞崩了。
- 连续的UI交互,如DOM拖拽,在窗口的resize事件、窗口的滚动scroll事件中更新UI,如果用防抖会有卡顿的现象,更适合用节流。
使用案例:滚动浏览器滚动条到末尾。
- 如果不用防抖函数,
scroll
事件频繁触发,共触发了29次。 - 加上节流函数,同样的速度移动,执行了4次,间隔均匀。
//移动浏览器滚动条到末尾
window.addEventListener('scroll', print); //执行了29次
//加上节流,延迟300ms
window.addEventListener('scroll', throttle(print, 300)); //执行了4次
let index = 0;
function print() {
console.log(index++);
}
️版权申明:版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀
JavaScript中的防抖与节流-图文版的更多相关文章
- 来聊聊JavaScript中的防抖和节流
目录 JavaScript防抖和节流 问题还原 防抖 什么是防抖 使用场景 节流 什么是节流 使用场景 JavaScript防抖和节流 问题还原 我们先来通过代码把常见的问题还原: <html& ...
- JavaScript 中的防抖和节流
什么是防抖 函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时.如下图,持续触发 scrol ...
- JavaScript中函数防抖、节流
码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14565642.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...
- JS中的防抖与节流
什么是防抖?and什么是节流?一起来开心的学习下吧. 首先什么是防抖:就是在一定的时间内事件只发生一次,比如你点击button按钮,1秒内任你单身30年手速点击无数次,他也还是只触发一次.举个例子,当 ...
- Js中的防抖与节流函数
1.何为防抖与节流函数呢? 1.防抖(debounce):通过setTimeout方式,在一定的时间间隔内,将多次触发的事件转化为一次触发.也就是说当一个用户一直触发这个函数,且每次触发函数的间隔小于 ...
- JS中的防抖和节流
JS-防抖和节流 在进行窗口的resize.scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕.此时我们可以采用debounce(防抖)和 ...
- JavaScript函数的防抖和节流
防抖 触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间 思路: 每次触发事件时都取消之前的延时调用方法 function debounce(fn) { let tim ...
- 输入防抖 vue # 输入搜索的时候 及时搜索的快速访问接口的 解决方案 vue 中使用防抖和节流
输入防抖 watch: { value (newVal, oldVal) { if (this.timer) { clearTimeout(this.timer) } this.timer = set ...
- 理解Linux系统中的load average(图文版)转
一.什么是load average? linux系统中的Load对当前CPU工作量的度量 (WikiPedia: the system load is a measure of the amount ...
- 理解Linux系统中的load average(图文版)
本文转自:http://heipark.iteye.com/blog/1340384 一.什么是load average? linux系统中的Load对当前CPU工作量的度量 (WikiPedia: ...
随机推荐
- vue基础之MV*和它们之间的不同
vue中的设计思想 vue中的设计思想主要是MV*模式,由最早的MVC(model-view-controller)框架,到后面的MVP(model-view-presenter),甚至到最后的MVV ...
- MatrixOne从入门到实践01——初识MatrixOne
初识MatrixOne 简介 MatrixOrigin 矩阵起源 是一家数据智能领域的创新企业,其愿景是成为数字世界的核心技术提供者. 物理世界的数字化和智能化无处不在.我们致力于建设开放的技术开源社 ...
- windows下利用_popen,_wpoen创建管道进行系统命令输出数据
转载: https://blog.csdn.net/greless/article/details/72383762 参考: http://www.linuxidc.com/Linux/2011-04 ...
- emqx启用JWT令牌认证(包含hmac-based和public-key)
emqx连接启用jwt令牌认证 jwt令牌 概述 JWT 即 JSON Web Tokens 是一种开放的,用于在两方之间安全地表示声明的行业标准的方法(RFC 7519). 组成 令牌的形式 xxx ...
- 规则引擎深度对比,LiteFlow vs Drools!
前言 Drools是一款老牌的java规则引擎框架,早在十几年前,我刚工作的时候,曾在一家第三方支付企业工作.在核心的支付路由层面我记得就是用Drools来做的. 难能可贵的是,Drools这个项目在 ...
- 【算法】基础DP
参考资料 背包九讲 一.线性DP 如果现在在状态 i 下,它上一步可能的状态是什么. 上一步不同的状态依赖于什么. 根据上面的分析,分析出状态和转移方程.注意:dp 不一定只有两维或者一维,一开始设计 ...
- MySQL 主从复制一主两从环境配置实战
MySQL 初始化 MySQL 主从复制是指数据可以从一个 MySQL 数据库服务器主节点复制到一个或多个从节点.MySQL 默认采用异步复制方式;从节点可以复制主数据库中的所有数据库或者特定的数据库 ...
- java程序员在交接别人的工作时如何保证顺利交接?
序言 各位好啊,我是会编程的蜗牛,作为java开发者,尤其是在职场混迹了多年的老手,肯定会遇到同事离职的情况,或者自己跳槽的情况,这些都免不了需要做好交接工作,不管是别人交接给我们,还是我们交接给别人 ...
- 2022-11-03 Acwing每日一题
本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的.同时也希望 ...
- 2022-11-02 Acwing每日一题
逆序对的个数 给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量. 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i<j 且 a[i]>a[j],则其为一个逆 ...