JavaScript 中的防抖和节流
什么是防抖
函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。如下图,持续触发 scroll 事件时,并不执行 handle 函数,当 1000 毫秒内没有触发 scroll 事件时,才会延时触发 scroll 事件。
防抖应用场景如下
- 搜索框输入查询,如果用户一直在输入中,没有必要不停地调用去请求服务端接口,等用户停止输入的时候,再调用,设置一个合适的时间间隔,有效减轻服务端压力。
- 表单验证
- 按钮提交事件。
- 浏览器窗口缩放,resize 事件 (如窗口停止改变大小之后重新计算布局) 等。
具体实现
非立即执行版
JAVASCRIPTfunction debounce(func, wait) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}非立即执行版的意思是触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
立即执行版
JAVASCRIPTfunction debounce(func,wait) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
let callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
}立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的
什么是节流
函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数。节流通俗解释就比如我们水龙头放水,阀门一打开,水哗哗的往下流,秉着勤俭节约的优良传统美德,我们要把水龙头关小点,最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴。如下图,持续触发 scroll 事件时,并不立即执行 handle 函数,每隔 1000 毫秒才会执行一次 handle 函数。
节流应用场景:
- 按钮点击事件
- 拖拽事件
- onScoll
- 计算鼠标移动的距离 (mousemove)
具体实现
时间戳版
JAVASCRIPTfunction throttle(func, wait) {
let previous = 0;
return function() {
let now = Date.now();
let context = this;
let args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}当高频事件触发时,第一次会立即执行(给 scroll 事件绑定函数与真正触发事件的间隔一般大于 delay,如果你非要在网页加载 1000 毫秒以内就去滚动网页的话,我也没办法 o (╥﹏╥) o),而后再怎么频繁地触发事件,也都是每 delay 时间才执行一次。而当最后一次事件触发完毕后,事件也不会再被执行了 (最后一次触发事件与倒数第二次触发事件的间隔小于 delay,为什么小于呢?因为大于就不叫高频了呀 (╹▽╹))。
定时器版
JAVASCRIPTfunction throttle(func, wait) {
let timeout;
return function() {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}当触发事件的时候,我们设置一个定时器,再次触发事件的时候,如果定时器存在,就不执行,直到 delay 时间后,定时器执行执行函数,并且清空定时器,这样就可以设置下个定时器。当第一次触发事件时,不会立即执行函数,而是在 delay 秒后才执行。而后再怎么频繁触发事件,也都是每 delay 时间才执行一次。当最后一次停止触发后,由于定时器的 delay 延迟,可能还会执行一次函数。
节流中用时间戳或定时器都是可以的。更精确地,可以用时间戳 + 定时器,当第一次触发事件时马上执行事件处理函数,最后一次触发事件后也还会执行一次事件处理函数。
定时器 + 时间戳版本
JAVASCRIPT// 节流throttle代码(时间戳+定时器):
var throttle = function(func, delay) {
var timer = null;
var startTime = Date.now();
return function() {
var curTime = Date.now();
var remaining = delay - (curTime - startTime);
var context = this;
var args = arguments;
clearTimeout(timer);
if (remaining <= 0) {
func.apply(context, args);
startTime = Date.now();
} else {
timer = setTimeout(func, remaining);
}
}
}在节流函数内部使用开始时间 startTime、当前时间 curTime 与 delay 来计算剩余时间 remaining,当 remaining<=0 时表示该执行事件处理函数了(保证了第一次触发事件就能立即执行事件处理函数和每隔 delay 时间执行一次事件处理函数)。如果还没到时间的话就设定在 remaining 时间后再触发 (保证了最后一次触发事件后还能再执行一次事件处理函数)。当然在 remaining 这段时间中如果又一次触发事件,那么会取消当前的计时器,并重新计算一个 remaining 来判断当前状态。
总结
函数防抖
将几次操作合并为一此操作进行。原理是维护一个计时器,规定在 delay 时间后触发函数,但是在 delay 时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。
函数节流
使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。
区别
函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数
而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。
文章参考
JavaScript 中的防抖和节流的更多相关文章
- 来聊聊JavaScript中的防抖和节流
目录 JavaScript防抖和节流 问题还原 防抖 什么是防抖 使用场景 节流 什么是节流 使用场景 JavaScript防抖和节流 问题还原 我们先来通过代码把常见的问题还原: <html& ...
- 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 ...
- JavaScript 中函数节流和函数去抖的讲解
JavaScript 中函数节流和函数去抖的讲解 我们都知道频繁触发执行一段js逻辑代码对性能会有很大的影响,尤其是在做一些效果实现方面,或者逻辑中需要进行后端请求,更是会导致卡顿,效果失效等结果,所 ...
- 使用rxjs以及javascript解决前端的防抖和节流
JavaScript实现方式: 防抖 触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间:思路:每次触发事件时都取消之前的延时调用方法: 举个例子:做一个自动查 ...
随机推荐
- HDU 5322 Hope
HDU 5322 Hope 考虑 $ dp[n] $ 表示 长度为 $ n $ 的所有排列的答案. 首先,对于一个排列来说,如果最大值在 $ i $ 位置,那么前 $ i - 1 $ 个数必然与 $ ...
- 洛谷 P5406 - [THUPC2019]找树(FWT+矩阵树定理)
题面传送门 首先看到这道题你必须要有一个很清楚的认识:这题新定义的 \(\oplus\) 符号非常奇怪,也没有什么性质而言,因此无法通过解决最优化问题的思路来解决这个问题,只好按照计数题的思路来解决, ...
- P7327 Dream and Discs
题目传送门. 题意简述:有 \(n\) 个数 \(a_1,a_2,\cdots a_n\),等概率选取区间 \(P_1,S_1\subseteq [1,n]\),\(P_2\subseteq P_1\ ...
- Excel-电话号码隐藏某几个数为*,起到保护信息作用;
9.电话号码隐藏某几个数为*,起到保护信息作用: 方法一: =SUBSTITUTE(AG2,MID(AG2,4,5),"*****") 解释函数: MID(目标字符串,裁剪起始位置 ...
- 基本绘图函数:plot的使用
注意:"##"后面是程序输出结果 例如: par("bg") # 命令 ## [1] "white" # 结果 基本绘图函数: plot:散 ...
- 错误笔记: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable) E: Unable to lock the administration di
亲测可用 --jack alexander@alexander-virtual-machine:~$ sudo apt-get install -y httpdE: Could not get loc ...
- UE4之Slate:纯C++工程配置
概述: Slate是UE4提供的UI框架,整个UE4 Editor UI都是使用Slate构建的: Slate的官方文档:[Slate UI框架] Slate底层内容,中文环境下能搜索到的有效资源也不 ...
- Angular Service设计理念及使用
官方认为组件不应该直接获取或保存数据, 它们应该聚焦于展示数据,而把数据访问的职责委托给某个服务. 而服务就充当着数据访问,逻辑处理的功能.把组件和服务区分开,以提高模块性和复用性. 1.依赖注入 注 ...
- Gradle安装与配置
一.Gradle安装 1.Gradle安装 (1)先安装JDK/JRE (2)Gradle下载官网 Gradle官网 (3)解压安装包到想安装到的目录.如D:\java\gradle-5.2.1 (4 ...
- "delete this" in C++
Ideally delete operator should not be used for this pointer. However, if used, then following points ...