函数防抖(debounce)
概念: 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
生活中的实例: 如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。
假设,我们观察的总时间为10秒钟,规定1秒作为一次事件的最小间隔时间。
如果触发事件的频率是 0.5s/次
,那么
函数防抖如图
因为始终没法等一秒钟就被再次触发了,所以最终没有一次事件是成功的。
函数实现:要了解函数防抖可以使用高阶函数的概念进行实现,
function debounce(fn, wait) {
let timer = null
return function (...args) {
clearTimeout(timer)
timer = setTimeout(() => {
fn.call(this, ...args)
}, wait);
}
}
function search(a, b, c) {
console.log('搜索', a, b, c)
}
let obj = {
test: 1
}
let debounceSearch = debounce(search, 300)
function btnClick() {
debounceSearch.call(obj, 1,2,3)
}
函数节流(throttle)
概念: 规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
生活中的实例: 我们知道目前的一种说法是当 1 秒内连续播放 24 张以上的图片时,在人眼的视觉中就会形成一个连贯的动画,所以在电影的播放(以前是,现在不知道)中基本是以每秒 24 张的速度播放的,为什么不 100 张或更多是因为 24 张就可以满足人类视觉需求的时候,100 张就会显得很浪费资源。
函数节流如图
同样,2s/次
大于了最小时间规定,所以每一次触发都生效。
函数实现:依然是使用高阶函数,每隔一段时间触发一次执行次数不会较少,周期性执行
function resizeFn() {
console.log('窗口尺寸变化')
}
function throttle(fn, wait) {
let currentTime = Date.now()
return function (...args) {
let nowTime = Date.now()
if (nowTime - currentTime > wait) {
fn.call(this, ...args)
currentTime = Date.now()
}
}
}
let throttleClick = throttle(handleClick, 1000)
function handleClick() {
console.log('点击了')
}
// let throttleResize = throttle(resizeFn, 3000)
// window.addEventListener('resize', throttleResize)