防抖
理解
在一段时间中只执行一次
在事件被触发时,延迟n秒后再触发回调函数,如果n秒内又触发了事件,则会重新开始计算时间(n秒内最后一次生效)
使用场景
-
输入框输入
-
缩放resize 浏览器缩放,重新渲染表格
定时器版
青春版
function debounce(){
let timer//使用到了闭包
return ()=>{
clearTimeout(timer)//清除定时器
timer=setTimeout(()=>{//设置定时器
console.log('执行一次')
},1000)
}
}
debounce()
完整版
function addOne(){
console.log('执行一次',arguments[2])
}
function debounce(fn,time){
let timer
return ()=>{
clearTimeout(timer)
timer=setTimeout(()=>{
fn.apply(this,arguments)//改变this和传入参数
},time)
}
}
debounce(addOne,1000,'!!!')
节流
理解
每间隔一段时间执行一次
一段时间内只能触发一次,如果这段时间内触发多次事件,只有第一次生效会触发回调函数,一段时间过后才能再次触发(n秒内第一次生效)
使用场景
-
鼠标点击,- 鼠标按下和鼠标悬停单位时间只执行一次
-
滚动事件,懒加载、滚动加载、加载更多或监听滚动条位置
-
防止高频点击提交,防止表单重复提交
定时器版
青春版
function throttle(){
let timer = null
return ()=>{
if(!timer){//如果定时器不存在,则执行一次,并产生一个定时器
console.log('执行一次')
timer = setTimeout(()=>{
timer = null//置为null,相当于清除定时器
},1000)
}
}
}
throttle()
完整版
function addOne(){
console.log('执行一次',arguments[2])
}
function throttle(fn,time){
let timer = null
return ()=>{
if(!timer){
fn.apply(this,arguments)//改变this和传入参数
timer = setTimeout(()=>{
timer = null
},time)
}
}
}
throttle(addOne,1000,'!!!')
时间戳版
青春版
function throttle(){
let last = 0
return ()=>{
let now = Date.now()
if(now - last > 1000){
console.log('执行一次')
last = now
}
}
}
throttle()
完整版
function addOne(){
console.log('执行一次',arguments[2])
}
function throttle(fn,time){
let last = 0
return ()=>{
let now = Date.now()
if(now - last > time){
fn.apply(this,arguments)
last = now
}
}
}
throttle(addOne,1000,'!!!')