解决的问题: 在资源有限的前提下,因而频繁执行DOM操作、资源加载等重行为,导致UI停顿甚至浏览器崩溃,为处理通常出现场景:onresize,scroll,mousemove ,mousehover等事件回调函数的无间断执行。
基本思想:
某些代码不可以在没有间断的情况下连续重复执行,降低产生回调的频率
下面模拟的 resize 窗口变动的事件
函数抖动:
什么要用函数抖动?
函数防抖: 防止函数执行过快,在连续执行的时候卡住
核心原理:停止函数的调用,当函数停下来的时候,就在规定时间后执行
抽象理解:放大招之前需要囤气,等时机成熟再把大招释放,避免重复使用大招,一来伤害低(执行效率),二来蓝量降低(系统性能)
// 事件的封印 发大招需要囤气
window.addEventListener('resize',beabounce(showWidth,1000),false)
// fn 为回调函数
// delay 为停下来后等待执行的时间
function beabounce(fn,delay){
var timer = null
return function(){
clearTimeout(timer)
// 封印住了,等你操作停下的时候才会执行
timer = setTimeout(function(){
fn()
},delay)
}
}
应用场景:
- 每次resize/scroll 触发的高频事件
- 文本输入验证控制(避免每次输入都重复调用事件,只在输入停顿的时间触发一次)
- 滚动加载更懂,用户停止滚动会判断是否滚动到页面底部
函数节流:
核心原理:防止函数执行过快,以一定的周期执行,如果超过周期时间间隔过大,就当作下一个周期,如果还没到周期时间,继续执行
抽象理解:等蓝量足够就释放技能,当蓝量不足的时候等待蓝满了,才释放技能,避免在蓝不够的时候释放低阶技能,伤害不足,
20190402005718.gifwindow.addEventListener('resize',throttle(showWidth,1000),false)
// 节流
// 以时间为周期执行
// 时间始终会执行,只是会押后,时间为你设定的最大周期时间
function throttle(fn, delay ){
var last = 0 // 开始计算的结束时间
return function(){
var curr = new Date()
if( (curr - last) > delay ) {
fn()
last = curr // 重新约定最后的时间
}
}
}
应用场景:
- mousemove 事件触发的回调函数
- 射击游戏的mousedown/keydown事件(单位事件只能发射一颗子弹)
- keyup 事件,高频的按键触发事件
- 滚动加载更多, 在滚动的过程中一定周期时间会判断一次
网友评论