1、节流和防抖的作用
节流和防抖都是作用于函数的,是为了限制函数的执行频率。在实际开发中,有一部分事件函数可能会被频繁触发,例如窗口的 resize、scroll 等事件,以及js动画事件,如果短时间内大量触发这些事件函数,很有可能会导致响应速度跟不上触发速度,造成浏览器延迟、卡顿甚至假死。为了避免这些现象就需要使用 节流或防抖。
2、节流
节流是指限制函数在一定时间范围内,无论触发多少次函数,函数都只执行一次。简单来说,就像是一个阀门,当函数开始执行之后,就把这个阀门关上,那么后面触发的函数就不能执行了。当函数执行结束后或间隔时间结束后,再把阀门放开,就可以再次触发并执行函数了。像是技能冷却时间,必须冷缺结束了,才能再次使用。
案例代码:
// 状态位 判断能否执行函数
var valid = true
// delay 是指 函数执行的间隔周期
function f(delay){
if(!valid){
// 休息时间 此时已经有函数在执行或者 还在间隔周期内 不能执行
return false
}
// 工作时间,执行函数并且在间隔周期内把状态位设为false 不允许执行下一次函数
valid = false
setTimeout(() => {
console.log('函数执行了')
valid = true; // 执行结束 或间隔周期结束 把状态为设置为 true 允许执行下一次函数
}, delay)
}
补充: 节流目前我在两个地方用到过,一是 JS 动画,只有当前动画执行结束之后,才能触发下一次动画。二是页面触底加载,只有当前触底加载的数据,加载完之后,才能再次触底加载。所以在这个地方我简单补充一下如何实现页面触底加载:
// 节流阀
var valid = true
// 监听页面滚动事件
window.onscroll = function() {
// 获取页面总高度
let scrollHeight = document.body.scrollHeight
// 获取页面被卷去的高度
let scrollTop = document.body.scrollTop
// 获取可视区域的高度
let clientHeight = document.body.clientHeight
// 距离底部10px范围内 开始加载数据
if(scrollHeight - 10 <= scrollTop + clientHeight) {
valid = false // 开始加载数据 关闭阀门
setTimeout(() => {
console.log('数据加载结束了')
valid = true; // 执行结束 把状态为设置为 true 允许执行下一次加载
}, 3000)
}
}
3、防抖
防抖是指当事件函数被触发之后,不是立即执行,而是等待一段时间 n 再去执行,如果在 时间n 内又触发了该事件函数,则 时间 n 重置,重新计时,直到在 时间n 内没有再触发事件,则去执行函数。简单来说,跟 JS 停止动画队列差不多,一段时间内只会执行最后一次触发的函数。
案例代码:
// 状态位 判断能否已经有函数被触发
var timer = false
// delay 是指等待的时间
function f(delay){
if(timer){
// 此时已经有函数被触发了,清除原有等待函数
clearTimeout(timer)
}
// 设置新的等待函数,等待时间重置
timer = setTimeout(() => {
console.log('函数被执行了')
},delay)
}