resize、scroll、mousemove 等事件会持续触发函数,希望过一段时间才能触发,就需要防抖和节流
防抖
就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
不立即执行
效果:
过规定时间才触发,接下去触发间隔小于规定时间,函数不生效,事件触发间隔大于规定时间,函数生效
原理:
创建一个防抖函数debounce,接受触发的函数名和间隔时间
debounce就是将触发函数进行包裹,形成闭包,里面定义一个setTimeOut定时器使规定函数多久触发,每次触发debounce就判断定时器存在与否,存在就清除。
就形成了每次触发就会把之前定时器清除,所以要是在小于规定时间操作,函数就不会被触发
function debounce(func,time){
let cleartime;
return function(){
let that = this //不改变this指向
let ags = arguments //将事件的数据传入
if(cleartime){clearTimeout(cleartime)}
cleartime = setTimeout(()=>{
func.apply(that,ags)
},time)
}
}
立即执行
function debounce(func,time){
let cleartime;
return function(){
let that = this //不改变this指向
let ags = arguments //将事件的数据传入
if(cleartime){clearTimeout(cleartime)}
if(!cleartime)(func.apply(that,ags)) //以cleartime为标志,要是第一次就直接运用
cleartime = setTimeout(()=>{
func.apply(that,ags)
},time)
}
}
自定义立即执行还是不立即执行
只要加一个判断就行了
debounce(func,time,isImmediate)
节流
就是指连续触发事件但是在 n 秒中只执行一次函数
时间戳版:
function throttle(func,time){
let preview = 0
return function(){
let now = Date.now()
let that = this //不改变this指向
let ags = arguments //将事件的数据传入
if(now-preview>=time){
func.apply(that,ags)
preview = now
}
}
}
定时器版
function throttle(func,time){
let time = null
return function(){
let that = this //不改变this指向
let ags = arguments //将事件的数据传入
if(!time){
time = setTimeout(()=>{
time = null
func.apply(that,ags)
},time)
}
}
}