- 前端开发中在处理 scroll resize input mousemove 等事件时,通常并不希望事件处理函数持续触发,防抖和节流能更好的解决这一问题.
- 为了便于演示持续触发事件的现象
<!-- html 代码 -->
<body>
<input style="width: 100%; outline: none;" type="text">
<div style="display: flex;">
<div class="showThis" style="height: 100px;background: #eee;flex: 1;"></div>
<div class="showEvent" style="height: 100px;background: rgb(179, 155, 155);flex: 1;"></div>
</div>
<script>
let input = document.querySelector('input');
let showThis = document.querySelector('.showThis')
let showEvent = document.querySelector('.showEvent')
input.oninput = valueChange
function valueChange(e) {
showThis.innerHTML = this.value
showEvent.innerHTML = e.target.value
}
</script>
</body>
效果如下:
如果在处理函数中执行一些更复杂的代码,比如 ajax 请求,那将造成性能消耗
防抖(debounce)
- 所谓防抖,就是指触发事件单位时间后,才执行该事件的处理函数,如果在 单位时间内又触发了事件,则会重新计时,以保证事件里面的代码在单位时间只执行一次
// 防抖函数
function debounce(func, wait) {
let timer = null
return function () {
const that = this
const args = [...arguments]
if (timer) clearTimeout(timer)
timer = setTimeout(func.bind(this, ...args), wait)
}
}
// 将事件处理函数用防抖函数处理
input.oninput = debounce(valueChange, 500)
此时效果:
防抖的效果是只会执行最后一次触发的函数
节流(throttle)
- 当事件触发之后,约定单位时间之内,事件里面的代码最多只能执行一次,所以,节流减少了单位时间内代码的执行次数,从而提高性能。。
// 节流函数
function throttle(func, wait) {
let timer = null
return function () {
const that = this
const args = [...arguments]
if (timer) return
timer = setTimeout(() => {
timer = null
func.apply(that, args)
}, wait)
}
}
// 将事件处理函数用节流函数处理
input.oninput = throttle(valueChange, 500)
此时效果:
节流的效果是每隔单位时间会执行一次函数
总结
- 防抖和节流都是为了解决频繁触发某个事件的情况造成的性能消耗。
- 防抖就是在触发事件后的一段时间内执行一次,例如:在进行搜索的时候,当用户停止输入后调用方法,节约请求资源
- 节流就是在频繁触发某个事件的情况下,每隔一段时间请求一次,类似打游戏的时候长按某个按键,动作是有规律的在间隔时间触发一次