防抖
定义
- 触发事件后 n 秒后才执行函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
-
使用场景
会被频繁触发的事件,但又不想让其频繁触发,比如输入搜索词、滚动、hover等等
实现原理(文字版)
前置知识:闭包
- 声明一个函数,例如 debounce;接收变量 回调函数func 和 防抖时间wait。
- 函数内声明变量 timeId,这个变量将供闭包使用,用来存储和销毁 setTimeout
- 通过将 debounce 函数的 return 置为 function,实现一个闭包,在闭包的匿名函数中,清除上一次的 setTimeout,开始本次的 setTimeout,setTimeout 中 调用回调函数 func。
- 声明over。
- 为对应的事件监听,执行 debounce 函数。保证对应事件发生时,执行的是debounce函数return的匿名函数。
实现(代码版)
// 声明
const debounce = function (func, wait = 1000) {
let timeId
return function (...arg) {
timeId && clearTimeout(timeId)
let self = this
timeId = setTimeout(() => {
func.apply(this, arg)
timeId = undefined
}, wait)
}
}
使用
// in vue
methods: {
test: debounce(function(a, b) {
console.log(a)
console.log(b)
})
}
节流
定义
- 触发事件后立即执行函数,如果在 n 秒中又触发了事件,不执行函数。
-
使用场景
-
实现
const throttle = function (func, wait = 1000) {
let timestamp = new Date().getTime()
return function (...args) {
const diff = new Date().getTime() - timestamp
if (diff > wait) {
func.apply(this, args)
timestamp = new Date().getTime()
}
}
}
实现(注释版)
const throttle = function (func, wait = 1000) {
// 用于计算两次事件触发之间的时间差,
let timestamp = 0
return function (...args) {
// 获取与上次函数执行的时间差
const diff = new Date().getTime() - timestamp
if (diff >= wait) {
// 当函数被执行了,更新时间戳
func.apply(this, args)
timestamp = new Date().getTime()
}
}
}