都属于优化页面性能的知识点。都是为了防止短时间内大量触发某函数而导致的页面延迟或卡顿的现象。
防抖:
什么是防抖?当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
防抖原理是维护一个定时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,都会清除当前的 timer 然后重新设置超时调用,即重新计时。这样一来,只有最后一次操作能被触发。
应用场景:1,用户在输入框输入一串字符,只会在输入最后一个字符完成后去执行Ajax请求,有效减少请求次数节约请求资源。2,window的resize,scroll事件。不断地调整浏览器的窗口大小、或者滚动时会触发对应事件,防抖让其只触发一次。
手写防抖:
<input type="submit">
<script>
const btn=document.getElementsByTagName('input')[0];
function payMoney(){
console.log(1);
}
//function debounce(fn){
// fn();
//}
function debounce(fn,delay){
let timer;
return function(){
let context=this;
let args=arguments;
clearTimeout(timer);
timer=setTimeout(()=>{
fn.apply(context,args);
},delay)
}
}
btn.addEventListener('click',debounce(payMoney,1000));//debounce()括号表示调用此函数,
</script>
节流:
什么是节流?在一个固定的时间间隔内,只能有一次触发事件的回调函数执行,如果在时间间隔内事件又被触发,并不会执行这个事件。
应用场景:页面无限加载的情况下,需要用户在滚动页面时,每隔一段时间去发送一次Ajax请求,而不是等用户停下滚动页面操作才开始发送Ajax请求。
手写节流:
function throttle(fn,delay){
let timer;
return function(){
let context=this;
let args=arguments;
if(timer){
return ;//timer为true被赋值了说明还在等待定时器计时完成,这时候不执行函数直接返回
}
//timer没被赋值或任务执行完了
timer=setTimeout(()=>{
fn.apply(context,args);//执行一次函数
timer=null;//函数延迟执行完要清空timer的值
},delay)
}
}
btn.addEventListener('click',throttle(payMoney,1000));
用date实现:
function throttle(fn,delay){
let pre=0;
return function(){
let context=this;
let args=arguments;
let now=new Date();
if(now-pre>delay){
fn.apply(context,args);
pre=now;
}
}
}
btn.addEventListener('click',throttle(payMoney,1000))
区别:
函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次事件处理函数,而函数防抖只是在最后一次事件后一段delay后才触发一次函数。