防抖节流

1.防抖

控制高频函数执行的次数,n秒内执行一次,当n秒内再次触法,则重新计算
应用:
窗口resize
scroll(窗口停止滚动触发操作)
表单验证
提交
输入框查询
let count = 0
const doSome = debounce(doSomething,3000)
container.onmousemove = doSome
function doSomething(e){
      container.innerText = ++count
}
btn.onclick = function () {
      doSome.cancel()
}
function debounce(fun,wait,immediate){
let timeout,result
const debounced = function () {
const context = this
const args = arguments
if(timeout)clearTimeout(timeout)
if(immediate){
let callNow = !timeout
timeout = setTimeout(()=>{
timeout = null
},wait)
if(callNow)result = fun.apply(context,args)
}else{
timeout = setTimeout(()=>{
result = fun.apply(context,args)
},wait)
}
return result
}

debounced.cancel = function () {
clearTimeout(timeout)
timeout = null
}
return debounced
}

 2.节流

高频函数持续执行,每隔一段时间执行一次
应用场景:
拖拽每隔一段时间进行操作
射击游戏每隔一段时间上子弹
scroll(每个一段时间执行操作)
计算鼠标移动距离
let count = 0
container.onmousemove = throttle(doSomething,1000,{leading:true,trailing:true})
function doSomething(e){
    container.innerText = ++count
}
// 时间戳实现
function throttle1(func,wait){
    let old = 0
let context,args
return () => {
context = this
args = arguments
const now = new Date().valueOf()
if(now - old > wait){
func.apply(context,args)
old = now
}
}
}
// 定时器实现
function throttle2(func,wait){
let timeout,context,args
return () => {
if(!timeout){
context = this
args = arguments
timeout = setTimeout(() => {
func.apply(context,args)
timeout = null
},wait)
}
}
}
// 完完整版
function throttle(func,wait,option){
let old = 0
let context,args
let timeout
if(!option)option = {}
const { leading,trailing } = option
return () => {
context = this
args = arguments
const now = new Date().valueOf()
if(leading === false && !old){
old = now
}
if(now - old > wait){
// 执行第一次
func.apply(context,args)
old = now
if(timeout){
clearTimeout(timeout)
timeout = null
}
} else if(!timeout && trailing){
// 执行最后一次
timeout = setTimeout(() => {
func.apply(context,args)
old = now
timeout = null
},wait)
}

}
}

  



posted @ 2021-08-26 22:43  卷叶小树  阅读(28)  评论(0编辑  收藏  举报