1. 节流
定义:在规定时间内,如果动作(事件)连续触发,节流后只触发一次。
// 定时器实现
function throttle(fn, delay = 100) {
let timer = null // 1
return function () {
if (timer) {
return
}
timer = setTimeout(() => {
fn.apply(this, arguments) // 2
timer = null
}, delay)
}
}
// 时间戳实现
function debounce(fn, delay = 500) {
let activeTime = 0
return function () {
let currentTime = Date.now()
if (currentTime - activeTime > delay) {
fn.apply(this, arguments)
activeTime = currentTime
}
}
}
myDiv.addEventListener('drag', throttle(function (e) {
console.log(e.offsetX, e.offsetY)
}))
2. 防抖
定义:在规定时间内,如果动作(事件)持续触发,则只触发规定时间后的最后一次动作。
function debounce(fn, delay = 500) {
let timer = null // 1
return function () {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments) // 2
timer = null
}, delay)
}
}
myInput.addEventListener('change', debounce(function (e) { // 3
console.log(myInput.value)
}, 600))
myInput.addEventListener('change', function(event) {
// 这里用来对比不使用防抖
})
需要注意的点
1.节流防抖中timer为闭包,会一直存在。
2.直接执行fn()可以吗?答案是可以的,也可以起到节流防抖的作用,但是会丢失参数和this。
3.调用debounce/throttle时候使用箭头函数,this会指向window。