防抖函数

在规定时间内重复触发时,会重新计时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* @description 在一定时间内,持续触发,会重新计时
* @param (fn, wait) fn-要防抖的函数, wait-延迟毫秒数
* @return 防抖动后的函数
*/
function debounce(fn, wait = 500) {
let timer = null
return function(...args) {
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, args)
timer = null
}, wait)
}
}

使用

1
<input type="input" id="username" />
1
2
3
4
5
6
7
8
9
10
11
12
 // JS部分
const inputEL = document.querySelector('#username')
const listenFn = debounce(function(event) {
console.log(event.target.value)
}, 200)
inputEL.addEventListener('input', listenFn)

// 避免修改窗口大小时,出现额外的开销
const resizeDebouncedFn = debounce(() => {
console.log('resize', window.innerWidth)
}, 300)
window.addEventListener('resize', resizeDebouncedFn)

节流函数

规定时间内,至少执行一次,通常用于限制执行频率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* @description 无论如何触发,在一定时间内必定执行一次
* @param (fn, wait) fn-需要节流的函数, wait-延迟毫秒数
* @return 新函数
*/
function throttle(fn, wait = 500) {
let timer = null
return function(...args) {
// 上一次定时器任务还没执行,什么都不做
if(timer) {
return
}
timer = setTimeout(() => {
fn.apply(this, args)
timer = null
}, wait)
}
}

使用

1
2
3
<div style="height: 300vh;background-color: skyblue;">
test scroll demo
</div>
1
2
3
4
5
6
7
8
window.addEventListener('resize', throttle(() => {
console.log(window.innerWidth)
}, 300))

// 在滚动过程中,每隔一段时间执行函数
window.addEventListener('scroll', throttle(() => {
console.log('scroll')
}, 200))