防抖(debounce)
防抖的作用:把频繁触发的动作放在最后执行一次。常见的行为就是搜索引擎的搜索输入(百度是每次都触发,没有使用防抖),只在用户完成输入后进行匹配搜索。
实现思路:设置一个延迟的定时器,每次触发时,都取消之前的定时器并重新设置,达到最后执行一次的效果。
function debounce(fn,delay=500,immediate){
let timer = null,immediateTimer = null;
return function(){
let args = arguments, context = this;
// 第一次触发
if(immediate && !immediateTimer){
fn.apply(context,args);
//重置首次触发标识,否则下个周期执行时会受干扰
immediateTimer = setTimeout(()=>{
immediateTimer = null;
},delay);
}
// 存在多次执行时,重置动作需放在timer中执行;
if(immediateTimer) clearTimeout(immediateTimer);
if(timer) clearTimeout(timer);
timer = setTimeout(()=>{
fn.apply(context,args);
timer = null;
immediateTimer = null;
},delay);
}
}
使用:
let temp = debounce((e) => {
console.log(this, e.target.value);
}, 500,true);
input.addEventListener('input', temp);
节流(throttle)
节流的作用:把频繁触发的动作按照一定周期执行。常见的行为就是滚动事件scroll,移动事件mousemove等。
实现思路:设置一个延迟的定时器,每次触发时,都重新设置定时器,达到最后执行一次的效果。
function throttle(fn, delay = 500, immediate = false) {
let timer = null,
immediateTimer = null,
immediateRunning = !immediate;
return function() {
let context = this, args = arguments;
if (immediate && !immediateRunning) {
fn.apply(context, args);
immediateRunning = true;
// // 重置首次执行标识
immediateTimer = setTimeout(()=>{
immediateRunning = false;
},delay);
return;
}
if(!timer){
// 如果有后续触发,在定时器中取消immediateTimer
if(immediateTimer) {
clearTimeout(immediateTimer);
immediateTimer = null;
};
timer = setTimeout(() => {
fn.apply(context, args);
timer = null;
immediateTimer = setTimeout(()=>{
immediateRunning = false;
},delay);
}, delay)
}
}
}
使用:
let temp = throttle((e) => {
console.log(this, e.target.value);
}, 500,true);
input.addEventListener('input', temp);