-
防抖
转载
让某个函数在一定 事件间隔条件(去抖debounce) 或 时间间隔条件(节流throttle) 下才会去执行,避免快速多次执行函数(操作DOM,加载资源等等)给内存带来大量的消耗从而一定程度上降低性能问题。
debounce: 当调用动作n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。
debounce使用场景:
- scroll事件(资源的加载)
- mouseover事件(拖拽)
- 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);
}
}
/* 方法执行e.g. */
var btn = document.getElementById('btn');
var el = document.getElementById('display');
var init = 0;
btn.addEventListener('click', debounce(function() {
init++;
el.innerText = init;
}, 1000,true));
- 截流
throttle:预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。
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);
}
}
}
/* 方法执行 */
var btn = document.getElementById('btn');
var el = document.getElementById('display');
var init = 0;
btn.addEventListener('click', throttle(function() {
init++;
el.innerText = init;
}, 1000));
或者:
function throttle(fn, threshhold, scope) {
threshhold || (threshhold = 250);
var last,
deferTimer;
return function () {
var context = scope || this;
var now = +new Date(),
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
fn.apply(context, args);
}, threshhold);
} else {
last = now;
fn.apply(context, args);
}
};
}
浙公网安备 33010602011771号