debounce(防抖函数)
function debounce(fn,delay){
let timer = null;
return function(){
clearTimeout(timer);
timer = setTimeout(()=>{
fn.apply(this,arguments)
},delay)
}
}
防抖函数:在事件被触发n秒后再执行回调函数,如果在这n秒内又被触发,则重新计时
使用场景:
-
用户在输入框中连续输入一串字符后,只会在输入完后去执行最后一次的查询ajax请求,这样可以有效减少请求次数,节约请求资源;
-
window的resize、scroll事件,不断地调整浏览器的窗口大小、或者滚动时会触发对应事件,防抖让其只触发一次;
throttle(节流函数)
function throttle(fn,time){
let flag = true;
return function(){
if(!flag) return; //flaga为false则结束
flag = false; //一次触发后变为false,在定时器改为true之前不再执行上下文内容
setTimeout(()=>{
fn.apply(this,arguments)
flag=true; //只有等到定时器事件触发,flag变为true,才有机会执行下一个定时器
},time)
}
}
时间戳方式:
function throttle(fn,time){
let pre = Date.now(); //保存初始时间
return function(){
let cur = Date.now(); //保存执行函数体的时间
if(cur-pre>time){ //计算时间间隔是否满足
setTimeout(()=>{
fn.apply(this,arguments);
pre=cur; //更新上一次的时间
},time)
}
}
}
节流函数:规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
应用场景
- 鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;
- 在页面的无限加载场景下,需要用户在滚动页面时,每隔一段时间发一次 ajax 请求,而不是在用户停下滚动页面操作时才去请求数据;
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断;
防抖是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,都会清除当前的 timer 然后重新设置超时调用,即重新计时。这样一来,只有最后一次操作能被触发
节流函数是通过一个时间戳,判断当前时间与上一次时间之差,如果在time后触发,就更新上一次时间。