addEventListener 第三个参数

addEventListener 的 options 和 useCapture 参数详解

问题

addEventListener 的第三个参数有什么作用?

解答

语法

addEventListener(type, listener); 
addEventListener(type, listener, options);
addEventListener(type, listener, useCapture);

参数说明

type:监听事件类型的字符串(大小写敏感)。

listener:事件触发时的回调函数,接收一个实现了 Event 接口的对象。

options(可选):配置对象,包含以下属性:

  • capture:布尔值,为 true 时在捕获阶段触发监听器
  • once:布尔值,为 true 时监听器只执行一次后自动移除
  • passive:布尔值,为 true 时表示监听器不会调用 preventDefault(),可提升滚动性能
  • signal:AbortSignal 对象,调用其 abort() 方法可移除监听器

useCapture(可选):布尔值,为 true 时在捕获阶段触发,默认为 false(冒泡阶段)。

示例

// 只执行一次
button.addEventListener('click', handler, { once: true });

// 捕获阶段触发
element.addEventListener('click', handler, { capture: true });

// 使用 signal 移除监听
const controller = new AbortController();
element.addEventListener('click', handler, { signal: controller.signal });
controller.abort(); // 移除监听器

// 优化滚动性能
element.addEventListener('scroll', handler, { passive: true });

事件传播

当元素嵌套时,事件传播分为三个阶段:

  1. 捕获阶段:从 window 向下传播到目标元素
  2. 目标阶段:到达目标元素
  3. 冒泡阶段:从目标元素向上冒泡到 window

捕获阶段的监听器会先于冒泡阶段的监听器执行。

关键点

  • options 对象可配置 captureoncepassivesignal 四个属性
  • once: true 可让监听器自动执行一次后移除
  • passive: true 可提升滚动性能,但监听器内不能调用 preventDefault()
  • capture 决定在捕获阶段还是冒泡阶段触发,默认为冒泡阶段
  • signal 配合 AbortController 可方便地移除监听器