1.防抖节流总结、使用、具象化理解
防抖(Debouncing)和节流(Throttling)都是在处理频繁触发的事件时,用于优化性能和避免过多资源消耗的技术。它们的应用场景和原理略有不同。
1. 防抖(Debouncing):
在防抖中,事件被触发后,如果在指定的时间间隔内没有再次触发,才会执行相应的操作。如果事件在规定时间内再次触发,则重新计时。
实现原理:
- 设定一个等待时间(例如300毫秒)。
- 当事件触发时,启动计时器。
- 如果在等待时间内再次触发事件,则重新计时。
- 如果计时器完成,表示事件没有在规定时间内再次触发,执行相应的操作。
实际运用场景:
- 输入框输入搜索:在用户输入完成后的短暂延时后再执行搜索操作,避免每次输入都触发搜索请求。
- 窗口大小调整:在调整窗口大小时,防止过于频繁触发resize事件。
防抖具象化:
其实防抖就是你打英雄联盟的回城,每次你按B回去,你再按一次B就会打断前面一次的回城,他只会执行你最后一次的操作,这样是不是就很好理解了
2. 节流(Throttling):
在节流中,事件被触发后,无论触发的频率有多高,只会在规定的时间间隔内执行一次相应的操作。
实现原理:
- 设定一个执行间隔(例如300毫秒)。
- 当事件触发时,如果距离上次执行的时间超过了设定的执行间隔,就执行相应的操作。
- 如果触发的频率高于设定的执行间隔,就忽略这次触发。
实际运用场景:
- 滚动事件:在处理滚动事件时,限制事件处理的频率,防止滚动时过多的计算和渲染。
- 鼠标移动:在处理鼠标移动事件时,限制事件处理的频率,防止过多的计算和更新。
节流具象化:
其实节流就是你打英雄联盟的技能,每次你释放完技能,在你技能的CD时间,这个技能都无法被再次释放,只有等CD转好了,才可以再次使用,这样是不是就很好理解了
总结:
- 防抖适用于在一系列连续触发的事件中,只关心最后一次触发的结果。
- 节流适用于频繁触发的事件,限制其处理的频率,保证在一定时间内只执行一次操作。
2.防抖节流代码实战
2.1防抖实战以及详解
// 防抖函数 要求
// 当持续触发事件,一定时间内没有再触发事件,事件处理函数才会再执行一次
// 当设定的事件来到之前,有一次触发了事件,就重新开始延时
var input = document.querySelector('#input')
// 防抖函数
function debounce(delay) {
// 让timer一直存储在内存中
let timer
return function (value) {
//我们要想清除这个timer,就必须让他一直保存在内存中,
// 如果不想打印之前的结果,就必须清除以前触发的定时器
clearTimeout(timer)
timer = setTimeout(() => {
console.log(value);
}, delay)
}
}
// 这里是先调用外层函数,传入1000的时间值
var debouncefunc = debounce(1000)
// 在键盘抬起的时候,一秒之后打印出结果,但是如果我再次输入,那么就清除上一步 ,只打印这一步的结果
input.addEventListener('keyup', (e) => {
// 现在的debouncefunc就相当于 return的内部函数
// 这个时候传入value的值再打印
// 当我们输入了下一次的值的时候,就是再次调用这个内层函数的时候
debouncefunc(e.target.value)
})
2.2节流实战以及详解
<script>
// 这个节流函数 关键的点其实 是在于函数的执行顺序
// 我们分析一下
// 定义一个flag为true,当页面滚动的时候,如果flag为 true 执行 setTimeout
// 接下里执行的并不是console.log('hello');,而是 flag = false,
// 当flag为false,那么setTimeout不再执行,此时我们需要让flag为 true,这个时候setTimeout可以执行了
// 但是,他有0.5s的延迟,也就是说,在这0.5s之中,无论你怎么操作,他都不会执行
// 等执行完flag = false之后,再执行console.log('hello');flag = true
let flag = true
window.onscroll = () => {
if(flag){
setTimeout(() => {
console.log('hello');
flag = true
},1000)
}
flag = false
console.log(1);
}
</script>
节流函数的封装
window.onscroll = closeFlows(function() {
console.log(111);
},500)
function closeFlows(fn,delay) {
let flag = true
return function(){
if(flag){
setTimeout(() => {
fn()
flag = true
},delay);
}
flag = false
}
}