EventTarget.addEventListener 和 EventTarget.removeEventListener 用法详解

https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener
https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/removeEventListener

1. EventTarget.addEventListener

EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。 事件目标可以是一个文档上的元素 Element,DocumentWindow或者任何其他支持事件的对象 (比如 XMLHttpRequest)

addEventListener()的工作原理是将实现EventListener的函数或对象添加到调用它的EventTarget上的指定事件类型的事件侦听器列表中。

1.1语法
target.addEventListener(type, listener, options);
target.addEventListener(type, listener, useCapture);
target.addEventListener(type, listener, useCapture, wantsUntrusted );  // Gecko/Mozilla only
1.2 参数
  • type

    表示监听事件类型的字符串。

  • listener

    当所监听的事件类型触发时,会接收到一个事件通知(实现了 Event 接口的对象)对象。listener 必须是一个实现了 EventListener 接口的对象,或者是一个函数。有关回调本身的详细信息,请参阅The event listener callback

  • options 可选

    一个指定有关 listener属性的可选参数对象。可用的选项如下:capture: Boolean,表示 listener 会在该类型的事件捕获阶段传播到该 EventTarget 时触发。once: Boolean,表示 listener 在添加之后最多只调用一次。如果是 true, listener 会在其被调用之后自动移除。passive: Boolean,设置为true时,表示 listener 永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。查看 使用 passive 改善的滚屏性能 了解更多.mozSystemGroup: 只能在 XBL 或者是 Firefox’ chrome 使用,这是个 Boolean,表示 listener被添加到 system group。

  • useCapture 可选

    Boolean,在DOM树中,注册了listener的元素, 是否要先于它下面的EventTarget,调用该listener。 当useCapture(设为true) 时,沿着DOM树向上冒泡的事件,不会触发listener。当一个元素嵌套了另一个元素,并且两个元素都对同一事件注册了一个处理函数时,所发生的事件冒泡和事件捕获是两种不同的事件传播方式。事件传播模式决定了元素以哪个顺序接收事件。进一步的解释可以查看 事件流JavaScript Event order 文档。 如果没有指定, useCapture 默认为 false 。

注意: 对于事件目标上的事件监听器来说,事件会处于“目标阶段”,而不是冒泡阶段或者捕获阶段。在目标阶段的事件会触发该元素(即事件目标)上的所有监听器,而不在乎这个监听器到底在注册时useCapture 参数值是true还是false。

注意: useCapture 仅仅在现代浏览器最近的几个版本中是可选的。 例如 Firefox 6以前的版本都不是可选的。为了能够提供更广泛的支持,你应该提供这个参数。

  • wantsUntrusted

    如果为 true, 则事件处理程序会接收网页自定义的事件。此参数只适用于 Gecko(chrome的默认值为true,其他常规网页的默认值为false),主要用于附加组件的代码和浏览器本身。

1.3 返回值

undefined.

2.EventTarget.removeEventListener

删除使用 EventTarget.addEventListener() 方法添加的事件。使用事件类型,事件侦听器函数本身,以及可能影响匹配过程的各种可选择的选项的组合来标识要删除的事件侦听器。

2.1 语法
target.removeEventListener(type, listener[, options]);
target.removeEventListener(type, listener[, useCapture]);
2.2 参数
  • type

    一个字符串,表示需要移除的事件类型,如 "click"

  • listener

    需要从目标事件移除的 EventListener 函数。

  • options 可选

    一个指定事件侦听器特征的可选对象。可选项有:

  • capture: 一个 Boolean 表示这个类型的事件将会被派遣到已经注册的侦听器,然后再派遣到DOM树中它下面的任何 EventTarget

  • mozSystemGroup: 仅可运行于 XBL 或者 Firefox Chrome,它是一个 Boolean,用于定义是否将侦听器添加到系统组。

  • useCapture 可选

    指定需要移除的 EventListener 函数是否为捕获监听器。如果无此参数,默认值为 false

    如果同一个监听事件分别为“事件捕获”和“事件冒泡”注册了一次,这两次事件需要分别移除。两者不会互相干扰。移除捕获监听器不会影响非捕获版本的相同监听器,反之亦然。

2.3 返回值

undefined.

2.4 匹配要删除的事件监听

需要提供以前调用addEventListener()所提供的监听事件, 这样你或许可以达到移除此监听事件的目的. 很明显, 你需要提供相同的 typelistener 参数给 removeEventListener(), 但是 options 或者 useCapture 参数呢?

当使用 addEventListener() 时, 如果 options参数不同, 那么你可以在相同的type 上多次添加相同的监听, 唯一需要 removeEventListener() 检测的是 capture/useCapture 标志. 这个标志必须与 removeEventListener() 的对应标志匹配, 但是其他的值不需要.

举个例子, 思考一下下面的 addEventListener():

element.addEventListener("mousedown", handleMouseDown, true);

现在思考下下面两个 removeEventListener():

element.removeEventListener("mousedown", handleMouseDown, false);     // 失败
element.removeEventListener("mousedown", handleMouseDown, true);      // 成功

第一个调用失败是因为 useCapture 没有匹配. 第二个调用成功,是因为useCapture 匹配相同.

现在再思考下这个:

element.addEventListener("mousedown", handleMouseDown, { passive: true });

这里, 我们在options 对象里将 passive 设成 true, 其他options配置都是默认值 false.

现在我们看下下面的 removeEventListener() . 当配置 captureuseCapturetrue 时, 移除事件失败; 其他所有都是成功的. 只有 capture 配置影响 removeEventListener().

element.removeEventListener("mousedown", handleMouseDown, { passive: true });     // Succeeds
element.removeEventListener("mousedown", handleMouseDown, { capture: false });    // Succeeds
element.removeEventListener("mousedown", handleMouseDown, { capture: true });     // Fails
element.removeEventListener("mousedown", handleMouseDown, { passive: false });    // Succeeds
element.removeEventListener("mousedown", handleMouseDown, false);                 // Succeeds
element.removeEventListener("mousedown", handleMouseDown, true);                  // Fails

值得注意的是,一些浏览器版本在这方面会有些不一致, 除非你有特别的理由, 使用与调用 addEventListener() 时配置的参数去调用removeEventListener()是明智的,也就是说两个方法的参数完全一致即可.

上一篇:Oracle 监听密码设置


下一篇:Filter、Listener学习笔记