防抖节流
大约 2 分钟
防抖节流
函数节流和防抖
函数节流和防抖都是优化频繁执行的事件,它们的区别就是是否过程中需要函数返回获取结果,节流,超过设定时间才会执行一次,在执行过程中会需要函数执行. 防抖,事件最后一次执行
节流
n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
- 滚动加载,加载更多或滚到底部监听
- 搜索框,搜索联想功能
// 简单版节流
function throttle(fn, delay) {
let oldtime = Date.now()
return function (...args) {
let newtime = Date.now()
if (newtime - oldtime >= delay) {
fn.apply(null, args)
oldtime = Date.now()
}
}
}
function throttled(fn, delay) {
let timer = null
let starttime = Date.now()
return function () {
let curTime = Date.now() // 当前时间
// 从上一次到现在,还剩下多少多余时间
let remaining = delay - (curTime - starttime)
let context = this
let args = arguments
clearTimeout(timer)
if (remaining <= 0) {
fn.apply(context, args)
starttime = Date.now()
} else {
timer = setTimeout(fn, remaining)
}
}
}
CSS 节流
css 节流通过使用pointer-events
禁用点击事件, 然后通过animation
结合:actived
通过动画效果设置在规定时间内,元素不可被点击, 节流时间通过设置动画效果控制。
点击以下示例,打开控制台,节流时间设置的两秒,console 打印结果
button {
animation: throttle 2s step-end forwards;
}
button:active {
animation: none;
}
@keyframes throttle {
from {
pointer-events: none;
}
to {
pointer-events: all;
}
}
防抖
n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测
- 窗口大小 resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
// 简单版防抖
function fangdou(fns, delay) {
let timer
return function () {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fns()
}, delay)
}
// return function() {
// const context = this
// const arg = arguments
// if (timer) clearTimeout(timer)
// timer = setTimeout(function(){
// fns.apply(context, arg)
// },delay)
// }
}
function debounce(func, wait, immediate) {
let timeout
return function () {
let context = this
let args = arguments
if (timeout) clearTimeout(timeout) // timeout 不为null
if (immediate) {
let callNow = !timeout // 第一次会立即执行,以后只有事件执行后才会再次触发
timeout = setTimeout(function () {
timeout = null
}, wait)
if (callNow) {
func.apply(context, args)
}
} else {
timeout = setTimeout(function () {
func.apply(context, args)
}, wait)
}
}
}