在处理诸如 resize、scroll、mousemove、keydown / keyup / keypress 等事件和输入框内容校验等操作的时候,通常我们不希望这些事件太过频繁地触发,尤其是监听程序中涉及到大量的计算或者有非常耗费资源的操作。此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少触发的频率,同时又不影响实际效果。
debounce 防抖
在 JavaScript 中,debounce 函数所做的事情就是,在用户停止某个操作一段时间之后才执行相应的监听函数,而不是在用户操作的过程当中,浏览器触发多少次事件,就执行多少次监听函数。
从上图中我们可以看到,当持续触发事件时,debounce会合并事件且不会去触发事件,当一定时间内没有触发再这个事件时,才真正去触发事件。
/**
*
* @param fn {Function} 实际要执行的函数
* @param delay {Number} 延迟时间,也就是阈值,单位是毫秒(ms)
*
* @return {Function} 返回一个防抖的函数
*/
function debounce(fn, delay) {
var ctx;
var args;
var timer = null;
var later = function () {
fn.apply(ctx, args);
// 当事件真正执行后,清空定时器
timer = null;
};
return function () {
ctx = this;
args = arguments;
// 当持续触发事件时,若发现事件触发的定时器已设置时,则清除之前的定时器
if (timer) {
clearTimeout(timer);
timer = null;
}
// 重新设置事件触发的定时器
timer = setTimeout(later, delay);
};
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
throttle 节流
当持续触发事件时,保证隔间时间触发一次事件。
上图中绿色块表示触发一次事件,持续触发事件时,throttle会合并一定时间内的事件,并在该时间结束时真正去触发一次事件。
/**
*
* @param fn {Function} 实际要执行的函数
* @param delay {Number} 执行间隔,单位是毫秒(ms)
*
* @return {Function} 返回一个“节流”函数
*/
function throttle(fn, delay) {
var ctx;
var args;
// 记录上次触发事件
var previous = Date.now();
var later = function () {
fn.apply(ctx, args);
};
return function () {
ctx = this;
args = arguments;
var now = Date.now();
// 本次事件触发与上一次的时间比较
var diff = now - previous - delay;
// 如果隔间时间超过设定时间,即再次设置事件触发的定时器
if (diff >= 0) {
// 更新最近事件触发的时间
previous = now;
setTimeout(later, delay);
}
};
}
本文暂时没有评论,来添加一个吧(●'◡'●)