debounce防抖函数
在n秒时间内连续触发事件只执行一次回调
实现1(连续时间内触发事件最后执行):
/**
* @param {*} fn 要执行的函数
* @param {*} delay 延迟的时间
*/
function debounce(fn,delay){
let timer
return function(...args){
const context = this
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(context,args)
}, delay);
}
}
实现2(先执行函数,在延时时间内不在执行):
function debounce(fn,delay){
let timer
return function(...args){
const context = this
let canExecute = !timer
if(canExecute){
fn.apply(contextt,args)
}else{
clearTimeout(timer)
}
timer = setTimeout(() => {
timer = null
}, delay);
}
}
应用场景:
- 提交按钮,防止重复提交
- input框 search查询时防止高频率接口调用
- 高频率触发onresize事件后最后一次执行的回调
throttle截流函数
频繁事件触发,在规定的时间执行一次事件处理函数
实现1(时间戳版):
function throttle(fn,delay){
let pre = 0
return function (...args){
const context = this
let now = Date.now()
if(now - pre >= delay){
fn.apply(context,args)
pre = Date.now()
}
}
}
实现2(计时器版):
function throttle(fn,delay){
let timer
return function(...args){
const context = this
if(!timer) {
timer = setTimeout(() => {
fn.apply(context,args)
timer = null
}, delay);
}
}
}
实现3(加强计时器版,优先执行一次函数):
function throttle (fn, delay) {
let timer, lastTime, first = true
return function (...args) {
const context = this
if (first) {
fn.apply(context, args)
first = false
lastTime = Date.now()
} else {
clearTimeout(timer)
timer = setTimeout(() => {
if (Date.now() - lastTime >= delay) {
fn.apply(context, args)
lastTime = Date.now()
}
}, Math.max((delay - (Date.now() - lastTime)), 0));
}
}
}
应用场景:
- 无限滚动列表,滚动到底加载更多