—连续尝试进行过多的DOM相关操作时,这很可能会导致浏览器挂起,有时候甚至崩溃
—此时,就需要节流和防抖来使某些代码不可以在没有间断的情况下连续重复的执行。
节流:让事务在一段时间间隔内周期性的执行(举个栗子:就好像不让水龙头一直不停的流,而是把水龙头揪紧一丢丢,让它一滴一滴周期性的流下去,以此达到节流的效果)
function throttle(func,wait){
let timeoutID; //初始化定时器
return function(){ //调用throttle则返回此闭包
let args=arguments; //保存传给闭包的参数
let context=this; //保存闭包的执行环境
if(!timeoutID){ //如果定时器不存在
timeoutID=setTimeout(function(){ //则创建一个新的定时器
func.apply(context,args); //绑定func的执行环境为调用闭包的this环境,传入func的参数为调用闭包的参数
timeoutID=null; //执行完func重置timeout
},wait); //在wait时间后将匿名函数插入执行队列
}
};
}
1.函数的目的是:定义一个定时器,如果定时器不存在,则创建一个新的定时器,并执行函数func;
2.函数返回闭包的原因:为了保持timeoutID变量一直在内存中,调用throttle函数返回的都是**执行过后**的闭包函数来访问timeoutID,通过timeoutID来判断调用throttle时是否存在定时器;
持续防抖:如果持续触发事务,则不执行,在停止持续触发事务一段时间后,再执行事务(举个栗子:一直按住弹簧,它不会弹起来,如果松手之后,在很微小的一段时间间隔内,它才会弹起,以此达到持续防抖的效果。虽然只是很微小的一瞬间,但是这对前端性能的影响却很巨大)
function debounce(func,wait){
let timeoutID;
return function(){
let context=this;
let args=arguments;
if(timeoutID!==null)clearTimeout(timeoutID); //如果存在定时器,则将清除定时器
timeoutID=setTimeout(function(){ //再次创建新的定时器
func.apply(context,args);
},wait);
};
}
立即防抖:让事务开始触发时立即执行,然后持续触发事务时不执行,当停止触发事务一段时间后再执行事务
function debounce(func,wait){
let timeoutID;
return function(){
let context=this;
let args=arguments;
if(timeoutID!==null)clearTimeout(timeoutID); //如果存在定时器,则清除定时器
timeout=setTimeout(function(){
timeout=null; //定时器在wait时间后清零
},wait)
let timer=!timeoutID;
if(timer) { //如果不存在定时器(timeout=null),则执行函数
func.apply(context,args);
}
};
}