防抖
function debounce(fn, delay = 200) {
let timer = 0
return function () {
let context = this
let args = [...arguments]
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(context, args)
}, delay);
}
}
// 非立即执行版本 在触发事件后函数 n 秒后才执行,而如果我在触发事件后的 n 秒内又触发了事件,则会重新计算函数执行时间。
function debounce(fn, delay = 200) {
let timer = 0
return function () {
let context = this
let args = [...arguments]
if (timer) clearTimeout(timer)
const callNow = !timer
timer = setTimeout(() => {
timer = 0
}, delay);
if(callNow) fn.apply(context, args)
}
}
// 立即执行版本,触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。
节流
function throttle(fn, delay = 1000) {
let timer = 0
return function () {
let context = this
let args = arguments
if(timer) return
timer = setTimeout(() => {
fn.apply(context, args)
timer = 0
}, delay);
}
}
// 非立即执行版,停止触发后会再执行一次
function throttle(fn, delay = 1000) {
let pre = 0
return function () {
let now = Date.now()
let context = this
let args = arguments
if(now - pre > delay){
fn.apply(context, args)
pre = now
}
}
}
// 时间戳立即执行版本
function throttle(fn, delay = 1000) {
let timer = 0, pre = 0
return function () {
let context = this
let args = [...arguments]
let now = Date.now()
let remaining = delay - (now - pre)
if(remaining <= 0 || remaining > delay){
if(timer) {
clearTimeout(timer)
timer = 0
}
pre = now
fn.apply(context, args)
}else if(!timer){
timer = setTimeout(() => {
pre = Date.now()
timer = 0
fn.apply(context, args)
}, remaining);
}
}
}
// 上面两种的结合,会在开始前和结束后都执行一次