- 节流–throttle,隔一段时间触发一次
用定时器实现节流,由于定时器的延迟性,最后可能还执行一次
function throttle1(fn, delay) {
let timer = null
return function () {
let args = arguments
let context = this
if (!timer) {
timer = setTimeout(() => {
fn.apply(context, args)
timer = null
}, delay)
}
}
}
时间戳节流,高频操作,最后一次时间间隔小,函数不在触发
function throttle2(fn, delay) {
let timer = null
let last = Date.now()
return function () {
let args = arguments
let context = this
let now = Date.now()
if (now - last >= delay) {
fn.apply(context, args)
last = now
}
}
}
- 防抖debounce,时间间隔内触发,定时器不断清除,只执行最后一次
function debounce(fn, delay) {
let timer = null
return function () {
let args = arguments
let context = this
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(context, args)
}, delay)
}
}
- 由于防抖只触发最后一次,中间没有响应,看起来像是页面卡死了,所以用节流优化下,打造一个有底线的debounce:delay时间内,还是不断创建新的定时器清除旧定时器,超出delay时间后,必须给一个响应
function betterDebounce(fn, delay) {
let timer = null,
last = 0
return function () {
let args = arguments
let context = this
let now = Date.now()
if (now - last < delay) {
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(context, args)
last = now
}, delay)
} else {
fn.apply(context, args)
last = now
}
}
}
function fn() {
console.log("hahahahah")
}
window.addEventListener("scroll", betterThrottle(fn, 1000))