防抖和节流问题,为什么要有防抖和节流?防抖和节流怎么解决?
问题:一个事件被频繁的调用,会加重浏览器的负担,造成浏览器卡顿;
解决问题:可以使用防抖和节流来解决
什么是防抖: 给一个限值200ms,滚动事件
(1)如果在200ms内没有再次触发滚动事件,那么就执行函数
(2)如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时
效果: 如果短时间内大量触发同一事件,只会执行-一次函数。
实现: 使用setTimeOut定时器
代码:
function debounce(fn, delay){
let timer = null //借助闭包
return function() {
if(timer){
clearTimeout(timer)
}
timer = setTimeout(fn,delay) //简化写法
}
//滚动事件
function showTop() {
var scrollTop = document. body . scrollTop|| document.documentElement . scrollTop;
console.1og( '滚动条位置: ' + scrollTop);
}
window.onscroll = debounce(showTop ,1000)
什么是节流:
类似控制阀门一样定期开放的函数,也就是让函数执行一次后,在某个时间段内暂时失效,过了这段时间后重新激活(类似于技能冷却时间)。
效果: 如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。
实现: 使用setTimeOut定时器
代码:
function throttle(fn, delay){
let valid = true
return function() {
if(!valid){
//休息时间暂不接客
return false
}
//工作时间,执行函数并且在间隔朗内把状态位没为无效
valid = false
setTimeout(() => {
fn()
valid = true;
}, delay)
}
}
//滚动事件
function showTop() {
var scrollTop = document. body . scrollTop|| document.documentElement . scrollTop;
console.1og( '滚动条位置: ' + scrollTop);
}
window.onscroll = debounce(showTop ,1000)
应用场景:
1.搜索框input事件,例如要支持输入实时搜索可以使用节流方案(间隔一段时间就必须查询相关内容),或者实现输入间隔大于某个值(如500ms) ,就当做用户输入完成,然后开始搜索,具体使用哪种方案要看业务需求。
2.页面resize事件,常见于需要做页面适配的时候。需要根据最终呈现的页面情况进行dom渲染(这种情形一般是使用防抖, 因为只需要判断最后- -次的变化情况)