防抖和节流
对于一些高频事件,比如窗口的resize, scroll, 输入框输入事件、鼠标移动等事件,如果这些事件处理函数比较复杂或者页面重新渲染的次数频繁,那么会给浏览器造成比较大的压力,性能低下,用户体验不好。这时候可以有相应的防抖或节流的方式减少函数触发的频率
防抖
对于持续触发的事件,会合并事件而不会立即执行;如果在一定的时间内没有再次触发这个事件,那么才会真正执行这个事件。
有两种方式:1. 非立即触发型 2. 立即触发型
1.非立即触发型
function debounce (fn, delay, ...rest) {
let timer
return function () {
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, rest)
}, delay)
}
}
2.立即触发
function debounce (fn, delay, ...rest) {
let timer
return function () {
if (timer) {
clearTimeout(timer)
}
let callNow = !timer
timer = setTimeout(() => {
timer = null
}, delay)
callNow && fn.apply(this, rest)
}
}
节流
节流:持续触发事件,在间隔时间内只触发一次
有两种方式: 1、时间戳版 2、定时器版
时间戳版
function throttle(fn,delay, ...rest) {
let prevTime
return function () {
let nowTime = Date.now()
if (nowTime - prevTime >= delay) {
fn.apply(this, rest)
preTime = Date.now()
}
}
}
定时器版
function throttle(fn, delay, ...rest) {
let timer
function () {
if (!timer) {
timer = setTimeout(() => {
timer = null
fn.apply(this, rest)
}, delay)
}
}
}
两者应用场景:
防抖:
1. 搜索框,在input中不断输入值时,用发抖来节省请求资源
2. 窗口的resize事件,不断的调整窗口的大小来触发事件,通过防抖只触发一次
节流:
1. 鼠标的onmousedown事件,鼠标不断点击时,单位时间内只触发一次
2. 窗口的scroll事件,比如滑动到底部自动加载更多