防抖:是持续发生事件,但有效执行内容在规定的时间。
节流:控制在2-3秒发生一次事件
防抖(debounce)
1. 原理
当持续触发事件,在一定时间内没有触发事件,事件才会处理函数一次,如果在设定时间到来之前,又触发事件,则重新开启定时器,执行最后一次触发事件
2. 应用场景
当有些事件触发频率太高,浏览器来不及处理会造成浏览器卡顿、掉帧等;
例如,回到顶部、立即(实时)搜索、输入框搜索自动补全事件、频繁点赞&取消点赞等。
mousemove onkeydown onkeyup onscroll onresize等
3. 代码实现
// 必须清理定时器
function debounce(callback, time = 1000){
let timer = null
return ()=>{
if( timer ){
clearTimeout(timer)
// timer = null
}
timer = setTimeout(()=>{
callback()
}, time)
}
}
window.onscroll = debounce(()=>{
console.log("调用了一次"); //注:log("要执行的事件")
},500);
或
let timer = null
document.querySelector('.input').onkeyup = ()=>{
if(timer !== null){
clearTimeout(timer)
}
timer = setTimeout(()=>{
console.log('防抖调用')
},1000)
}
节流
1. 原理
在一定时间间隔内只执行一次,在这段时间内无视后来产生的函数调用请求
2. 应用场景
DOM拖拽,浏览器的resize、scroll,鼠标的mousemove、mouseover等事件在触发时会不断绑定事件上的回调函数,浪费资源、降低性能,这时需要用防抖函数来进行调用次数的限制
3. 代码实现
function throlle(callback, time){
let lastTime = new.Date().getTime()
return ()=>{
let now = new.Date().getTime()
if( now - lastTime > time ){
callback()
lastTime = now
}
}
}
window.onscroll = throlle(()=>{
console.log("调用了一次");
}, 1000)
或
let timer = null
document.querySelector('.box').mouseover= ()=>{
if(timer !== null){
return
}
timer = setTimeout(()=>{
console.log('节流调用')
timer = null
}, 1000)
}
区别
-
相同点
a. 试用场景都是当有些事件触发频率太高,浏览器来不及处理会造成浏览器卡顿、掉帧等
b. 都可以通过setTimeout实现,目的是降低回调执行频率,节省资源,提高性能 -
不同点
防抖:在一段连续事件操作结束后处理回调,将多次出阿发变成一次触发,一定时间内连续触发的事件只在最后一次执行
节流:减少一段时间的触发频率,一段连续操作中每一段时间只执行一次,侧重于一段时间内只执行一次