debounce
去抖
定义
如果一个函数持续地触发,那么只在它结束后过一段时间只执行一次。
使用场景
scroll
事件(资源的加载)mousemove
事件(拖拽)resize
事件(响应式布局样式)keyup
事件(输入框文字停止打字后才进行校验)
示例代码
/**
* fn函数在最后一次调用时刻的delay毫秒之后执行
* @param fn 执行函数
* @param delay 时间间隔
* @param isImmediate 为true,debounce会在delay时间间隔的开始时立即调用这个函数
* @returns {Function}
*/
function debounce(fn, delay, isImmediate) {
var timer = null; //初始化timer,作为计时清除依据
return function() {
var context = this; //获取函数所在作用域this
var args = arguments; //取得传入参数
clearTimeout(timer);
if(isImmediate && timer === null) {
//时间间隔外立即执行
fn.apply(context,args);
timer = 0;
return;
}
timer = setTimeout(function() {
fn.apply(context,args);
timer = null;
}, delay);
}
}
// 调用方法
document.addEventListener('click', debounce(function() {
console.log('点击一次');
}, 1000, true));
示例demo:点我查看
该函数接收三个参数:
- 分别是要执行的函数fn、
- 事件完成周期时间间隔delay(即事件间隔多少时间内不再重复触发)
- 是否在触发周期内立即执行isImmediate。需要注意的是要给执行函数绑定一个调用函数的上下文以及对应传入的参数。示例中对click事件进行了去抖,间隔时间为1000毫秒,为立即触发方式,当不停点击按钮时,第一次为立即触发,之后直到最后一次点击事件结束间隔delay秒后开始执行加1操作。
throttle
节流
定义
如果一个函数持续的,频繁地触发,那么让它在一定的时间间隔后再触发。
使用场景
click
事件(不停快速点击按钮,减少触发频次)scroll
事件(返回顶部按钮出现\隐藏事件触发)keyup
事件(输入框文字与显示栏内容复制同步)- 减少发送
ajax
请求,降低请求频率
示例代码
/**
* 创建并返回一个像节流阀一样的函数,当重复调用函数的时候,最多每隔delay毫秒调用一次该函数
* @param fn 执行函数
* @param delay 时间间隔
* @returns {Function}
*/
function throttle(fn, delay) {
var timer = null;
var timeStamp = new Date();
return function() {
var context = this; //获取函数所在作用域this
var args = arguments; //取得传入参数
if(new Date()-timeStamp>delay){
timeStamp = new Date();
timer = setTimeout(function(){
fn.apply(context,args);
},delay);
}
}
}
//调用方法
document.addEventListener('click', throttle(function() {
console.log('点击一次');
}, 1000));
示例demo:点我查看
该函数接收两个参数:
- 要执行的函数fn
- 事件完成周期时间间隔delay(即事件间隔多少时间内不再重复触发)。
需要注意的是要给执行函数绑定一个调用函数的上下文以及对应传入的参数,以及在闭包外层的timeStamp时间记录戳,用于判断事件的时间间隔。
如果还是不能完全体会 debounce
和 throttle
的差异,可以到 这个页面 看一下两者可视化的比较
如果想了解更多,可阅读以下文档:
《Lodash》
《Underscore》