1. 事件频繁触发可能造成的问题?
- 一些浏览器时间:
window.onresize、window.mousemove 等,触发的频率非常高,会造成浏览器性能问题(浪费)
- 如果向后台发送请求,频繁触发,对服务器造成不必要的压力
2. 如何限制事件处理函数频繁调用?
3. 函数节流(throttle)
- 理解:
- 在函数需要频繁触发时:(事件频繁触发,函数频繁调用)
- 函数执行一次后,只有大于设定的执行周期后才会执行第二次
- 适合多次事件按时间做平均分配触发
- 固定的时间内,只有一次有效,第二次要大于指定的时间才会继续触发
- 间隔指定的时间就调用一下
- 场景:(需要中间的变化过程就用节流)
- 窗口调整 (resize)
- 页面滚动 (scroll)
- DOM 元素的拖拽功能实现 (mousemove)
- 抢购疯狂点击 (mousedown)
4. 函数防抖(debounce)
- 理解:
- 在函数需要频繁触发时:(事件频繁触发,函数频繁调用)
- 适合多次事件一次响应的情况
- 下一次的点击和这一次的点击要大于限定的间隔时间,那么才会触发
- 最后一次点击完毕之后,过了限定的间隔时间才会调用
- 场景:(只看最终结果)
- 实时搜索联想 (keyup)
- 文本输入的验证(连续输入文字后发送 AJAX 请求验证,验证一次就好)
- 判断 scroll 是否滑到底部,滚动事件 + 函数防抖
实际开发中看需求选用
<body>
<button id="throttle">测试函数节流</button>
<button id="debounce">测试函数防抖</button>
<script>
function handleClick() {
console.log('处理点击事件')
}
function throttle(callback, delay) {
let startTime = 0
return function () {
console.log('throttle 事件...')
const currentTime = Date.now()
if (currentTime - startTime > delay) {
callback.apply(this, arguments)
startTime = currentTime
}
}
}
document.getElementById('throttle').onclick = throttle(handleClick, 1000)
function debounce(callback, delay) {
return function () {
console.log('debounce 事件...')
const that = this
const args = arguments
if (callback.timeoutId) {
clearTimeout(callback.timeoutId)
}
callback.timeoutId = setTimeout(function () {
callback.apply(that, args)
delete callback.timeoutId
}, delay)
}
}
document.getElementById('debounce').onclick = debounce(handleClick, 1000)
</script>
</body>