JS函数节流和函数防抖
栏目: JavaScript · 发布时间: 5年前
内容简介:防抖(如果一个事件被频繁触发多次,并且触发的时间间隔过短,则防抖函数可以使得对应的事件处理函数只执行最后触发的一次。 函数防抖可以把多个顺序的调用合并成一次。如果一个事件被频繁触发多次,节流函数可以按照固定频率去执行对应的事件处理方法。 函数节流保证一个事件一定时间内只执行一次。
-
在浏览器中某些计算和处理要比其他的昂贵很多。例如
DOM
操作比起非DOM
交互需要更多的内存和CPU占用时间。连续尝试进行过多的DOM
操作可能会导致浏览器挂起,甚至崩溃; -
例如当调整浏览器大小的时候,
resize
事件会连续触发;如果在resize
事件处理程序内部尝试进行DOM
操作,其高频率的更改可能会让浏览器崩溃; - 为了绕开上面的问题,需要对该类函数进行节流;
2.什么是函数防抖和函数节流
防抖(
debounce
)和节流(
throttle
)都是用来控制某个函数在一定时间内执行多少次的技巧,两者相似而又不同。
背后的基本思想是 某些代码不可以在没有间断的情况下连续重复执行。
2.1 函数防抖 ( debounce
)
如果一个事件被频繁触发多次,并且触发的时间间隔过短,则防抖函数可以使得对应的事件处理函数只执行最后触发的一次。 函数防抖可以把多个顺序的调用合并成一次。
2.2 函数节流 ( throttle
)
如果一个事件被频繁触发多次,节流函数可以按照固定频率去执行对应的事件处理方法。 函数节流保证一个事件一定时间内只执行一次。
3.应用场景
类型 | 场景 |
---|---|
函数防抖 |
1. 手机号、邮箱输入检测 2. 搜索框搜索输入(只需最后一次输入完后,再放松Ajax请求) 3. 窗口大小 resize
(只需窗口调整完成后,计算窗口大小,防止重复渲染) 4.滚动事件 scroll
(只需执行触发的最后一次滚动事件的处理程序) 5. 文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,(停止输入后)验证一次就好 |
函数节流 |
1. DOM
元素的拖拽功能实现( mousemove
) 2. 射击游戏的 mousedown
/ keydown
事件(单位时间只能发射一颗子弹) 3. 计算鼠标移动的距离( mousemove
) 4. 搜索联想( keyup
) 5. 滚动事件 scroll
,(只要页面滚动就会间隔一段时间判断一次) |
4.如何实现
4.1 函数防抖实现
function debounce(fn, delay, scope) { let timer = null; // 返回函数对debounce作用域形成闭包 return function () { // setTimeout()中用到函数环境总是window,故需要当前环境的副本; let context = scope || this, args = arguments; // 如果事件被触发,清除timer并重新开始计时 clearTimeout(timer); timer = setTimeout(function () { fn.apply(context, args); }, delay); } } 复制代码
- 代码解读
- 第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码;
- 当第二次调用该函数时,它会清除前一次的定时器并设置另一个;
- 如果前一个定时器已经执行过了,这个操作就没有任何意义;
- 然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器;
-
目的是
只有在执行函数的请求停止了
delay
时间之后才执行 。
4.2 函数节流实现
4.2.1 利用时间戳简单实现
function throttle(fn, threshold, scope) { let timer; let prev = Date.now(); return function () { let context = scope || this, args = arguments; let now = Date.now(); if (now - prev > threshold) { prev = now; fn.apply(context, args); } } } 复制代码
4.2.2 利用定时器简单实现
function throttle2(fn, threshold, scope) { let timer; return function () { let context = scope || this, args = arguments; if (!timer) { timer = setTimeout(function () { fn.apply(context, args); }, threshold); } } } 复制代码
5 举例( scroll
事件)
CSS代码
.wrap { width: 200px; height: 330px; margin: 50px; margin-top: 200px; position: relative; float: left; background-color: yellow; } .header{ width: 100%; height: 30px; background-color: #a8d4f4; text-align: center; line-height: 30px; } .container { background-color: pink; box-sizing: content-box; width: 200px; height: 300px; overflow: scroll; position: relative; } .content { width: 140px; height: 800px; margin: auto; background-color: #14ffb2; } 复制代码
HTML代码
<div class="wrap"> <div class="header">滚动事件:普通</div> <div class="container"> <div class="content"></div> </div> </div> <div class="wrap"> <div class="header">滚动事件:<strong>加了函数防抖</strong></div> <div class="container"> <div class="content"></div> </div> </div> <div class="wrap"> <div class="header">滚动事件:<strong>加了函数节流</strong></div> <div class="container"> <div class="content"></div> </div> </div> 复制代码
JS代码
let els = document.getElementsByClassName('container'); let count1 = 0,count2 = 0,count3 = 0; const THRESHOLD = 200; els[0].addEventListener('scroll', function handle() { console.log('普通滚动事件!count1=', ++count1); }); els[1].addEventListener('scroll', debounce(function handle() { console.log('执行滚动事件!(函数防抖) count2=', ++count2); }, THRESHOLD)); els[2].addEventListener('scroll', throttle(function handle() { console.log(Date.now(),', 执行滚动事件!(函数节流) count3=', ++count3); }, THRESHOLD)); 复制代码
// 函数防抖 function debounce(fn, delay, scope) { let timer = null; let count = 1; return function () { let context = scope || this, args = arguments; clearTimeout(timer); console.log(Date.now(), ", 触发第", count++, "次滚动事件!"); timer = setTimeout(function () { fn.apply(context, args); console.log(Date.now(), ", 可见只有当高频事件停止,最后一次事件触发的超时调用才能在delay时间后执行!"); }, delay); } } 复制代码
// 函数节流 function throttle(fn, threshold, scope) { let timer; let prev = Date.now(); return function () { let context = scope || this, args = arguments; let now = Date.now(); if (now - prev > threshold) { prev = now; fn.apply(context, args); } } } 复制代码
以上所述就是小编给大家介绍的《JS函数节流和函数防抖》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
HTML5移动应用开发入门经典
凯瑞恩 / 林星 / 人民邮电出版社 / 2013-3 / 55.00元
《HTML5移动应用开发入门经典》总共分为24章,以示例的方式对如何使用HTML5及相关技术进行移动应用开发做了全面而细致的介绍。《HTML5移动应用开发入门经典》首先讲解了HTML5的起源以及它为什么适用于移动设备,然后讲解了HTML5的基本元素以及所做的改进、canvas(画布)、视音频、微格式、微数据、拖曳等新增特性,还讲解了WebSocket、WebWorkers、Web存储、离线Web应......一起来看看 《HTML5移动应用开发入门经典》 这本书的介绍吧!