为什么要引入防抖节流
当一个函数被频繁触发、调用时,会严重加重浏览器的负担,造成浏览器卡顿的现象。因此引入防抖、节流来限制函数的执行频次,以优化函数触发频率过高引起的响应速度跟不上触发频率,出现延迟、假死或卡顿的现象。
防抖 debounce
当事件被频繁触发后,延迟n秒再执行该事件。如果n秒内再次触发,则重新计时
特点:停止触发n秒后,事件处理函数才会执行一次
场景:1、用户多次点击搜索、登录、导出按钮; 2、搜索框输入在输入完成之后才执行查询的请求;3、窗口Resize事件在调整完之后再计算窗口大小,防止重复触发回流重绘
作用:采用防抖策略,可以有效减少请求次数,节约请求资源
封装防抖函数:
<input id="input1" type="text">
const input1 = document.getElementById('input1')
function debounce(fn,delay){
let timer = null
return function (...args){
//n秒内重复触发 计时器重新开始计时
if(timer) clearTimeout(timer)
timer = setTimeout(()=>{
fn.apply(this,args)
timer = null
},delay)
}
}
input1.addEventListener('keyup',debounce(()=>{
console.log(input1.value)
},500))
节流 throttle
当事件被持续触发,每隔n秒执行事件一次
特点:按照一定频率,“匀速等距离”触发事件处理函数
场景:1、鼠标连续移动不断触发某事件/拖拽元素,要拿到元素被拖拽过程中移动的位置;2、搜索框输入联想的功能 3、懒加载监听滚动条的位置,但不必要每次滚动都监听
作用:采用节流策略降低触发频率,节约cpu资源
封装节流函数:
<span id="div1" draggable="true" style=“background:pink”>拖拽元素</span>
const span1 = document.getElementById('span1')
function throttle (fn,delay=100){
let timer = null
return function(...args){
//n秒内再次触发 直接返回,忽略本次触发事件
if(timer) return
timer = setTimeout(()=>{
fn.apply(this,args)
timer = null
},delay)
}
}
span1.addEventListener('drag',throttle(e)=>{
console.log(e.offsetX,e.offsetY)
},200)
两者区别比较
事件频发触发,防抖只能保证停止触发n秒后执行一次,前面的多次触发都会被忽略;而节流是指事件频繁触发时,按照一定的频率有选择性的执行一部分事件