防抖:当一个动作连续触发,只执行最后一次。
function debounce(fn, delay) {
// timer 是在闭包中的
let timer = null
return () => {
if (timer) { // 如果有就清空计时器
clearTimeout(timer)
}
timer = setTimeout(() => { // 定时器必须命名,要不然上面的if和清除就找不到了
fn.apply(this, arguments)
timer = null // 如果是防抖,可以不写,但是为了垃圾回收编码变量timer
}, delay)
}
}
let div1 = document.getElementById ('inner')
div1.addEventListener('click', debounce(()=>{
console.log(this)
}, 2000))
节流:一定时间内只能执行一次
function throttle(fn, delay) {
// timer 是在闭包中的
let timer = null
return () => {
if (timer) { // 如果有就跳过
return
}
fn.apply(this, arguments) // 放上面是间隔内立刻执行
timer = setTimeout(() => {
// fn.apply(this, arguments) // 放这里是间隔内最后一刻执行
timer = null // 必须写,且不能用clearTimeout,否则timer一直为一个编码,在if里出不来
}, delay)
}
}
let div2 = document.getElementById('inner')
div2.addEventListener('click', throttle(function(e) {
console.log(this)
}, 2000))
1、timer=null 和 clearTimeout区别:参考链接
- clearTimeout:清除计时器的效果(适用于防抖效果),但是timer依然是一个数组编码
- timer=null:计时器依然存在,只是和timer指针断开连接
2、首先定时器到期是类似于clearTimeout的效果,并没有将timer设为null
timer = setTimeout(() => { // 定时器必须命名,要不然上面的if和清除就找不到了
timer = null
}, 2000)
let div1 = document.getElementById ('inner')
div1.addEventListener('click', ()=>{
console.log(timer)
}) // 连续点击,一直打印同一个编码,两秒后打印null