Skip to content

createThrottledEventListener

创建带节流功能的事件监听器,有效减少高频事件的触发次数。

前置依赖

依赖参数

参数名类型说明
deps.addEventListenerWindow['addEventListener']添加事件监听器
deps.removeEventListenerWindow['removeEventListener']移除事件监听器
deps.setTimeouttypeof setTimeout设置定时器
deps.clearTimeouttypeof clearTimeout清除定时器
deps.now() => number获取当前时间戳(毫秒)

环境要求

  • 浏览器环境: 使用 Window 对象的事件监听 API 和定时器 API
typescript
// 浏览器环境
const deps = {
  addEventListener: window.addEventListener.bind(window),
  removeEventListener: window.removeEventListener.bind(window),
  setTimeout,
  clearTimeout,
  now: () => Date.now()
}

函数签名

typescript
function createThrottledEventListener(
  eventType: ThrottledEventType,
  callback: () => void,
  throttleMs: number,
  deps: CreateThrottledEventListenerDeps
): () => void

type ThrottledEventType = 
  | 'resize'
  | 'scroll'
  | 'mousemove'
  | 'touchmove'
  | 'pointermove'
  | 'wheel'

interface CreateThrottledEventListenerDeps {
  addEventListener: Window['addEventListener']
  removeEventListener: Window['removeEventListener']
  setTimeout: typeof setTimeout
  clearTimeout: typeof clearTimeout
  now: () => number
}

参数

参数名类型必填说明
eventTypeThrottledEventType事件类型(resize、scroll、mousemove 等)
callback() => void事件回调函数
throttleMsnumber节流时间(毫秒),设为 0 则不节流
depsCreateThrottledEventListenerDeps依赖注入对象

返回值

类型说明
() => void清理函数,调用后移除事件监听器并清除未执行的定时器

工作原理

  1. 节流时间为 0:直接添加事件监听器,每次事件都会触发回调
  2. 节流时间 > 0:实现 leading + trailing 节流模式
    • Leading(首次立即执行):首次触发事件时立即执行回调
    • 节流期内:连续触发事件时,只保留最后一次的延迟执行(trailing)
    • Trailing(最后一次延迟执行):在节流期结束后执行最后一次回调
  3. 清理机制:返回的清理函数会移除事件监听器并清除所有未执行的定时器

这种设计特别适合处理高频事件(如 resize、scroll、mousemove),在保证响应性的同时避免性能问题。

节流示例

假设节流时间为 200ms:

时间轴: 0ms    50ms   100ms  150ms  200ms  250ms  300ms
事件:   ●      ●      ●            ●
回调:   ✓(leading)                       ✓(trailing)
        ↑                                 ↑
        立即执行                     延迟执行(最后一次)