防抖
何为防抖:你尽管触发事件,我一定会在事件n秒后去执行事件,你不断触发了事件,那么我就以你的每次触发时间为最新,重新计时,之前的都不算
简单实现原理思路:(这里以点击不断的点击事件为例子)
用户每次点击按钮,都会开始重新计时,所以这里就需要一个定时器,每次用户点击,都要去清除定时器,这时候我们需要将定时器的id保存起来,用以清除定时器,这里就需要考虑这个定时器的id保存在哪里了,这个定时器的id应该被保存起来的,不能我们每一给触发事件,就重新赋值,这样就不行了,所以我们考虑用闭包来保存这个值,用户每次点击都要检查定时器id时候为空,如果为空,则清空定时器,重新计时
// 手写防抖---简单实现
document.querySelectorAll('button')[0].addEventListener('click', debounce(handle, 1000))
function handle() {//要防抖的函数
console.log("小凡好帅啊")
}
function debounce(fn, delay) {
// 只产生一个闭包
let timeId = null
return function () {
//用户每次点击都会进到这里来
clearTimeout(timeId)
timeId = setTimeout(fn, delay)
}
}
节流
何为节流: 节流就是规定一段事件,在这段时间内,不管怎么触发,都不起作用,只有等到规定时间到了,才开始执行,类似于王者荣耀的技能冷却时间,
简单分析思路: (还是以疯狂点击按钮事件为例子)
在规定事件内,触发事件都无效,这时候我们就可以想,我们可以用户第一次点击按钮,我们可以按照传入的事件,开始计时,之后用户不管怎么点击都没效果,这时候我们考虑用闭包来储存一个布尔变量,默认为true,当第一次点击的时候,开始计时,然后将变量赋值为false,之后在传入的时间到了之后,再将变量重新赋值为true,这样就可以实现我们需要的效果
具体实现代码:
document.querySelectorAll('button')[1].addEventListener("click", throttle(f2, 1000))
function f2() {//要节流的函数
console.log("节流")
}
function throttle(fn, delay) {
let flag = true
return function () {
if (!flag) {
return
}
setTimeout(() => {
fn.apply(this,arguments)
flag = true
}, delay)
flag = false//过河拆桥
}
}