EventTarget.removeEventListener()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2021.

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

调用 removeEventListener() 时,若传入的参数不能用于确定当前注册过的任何一个事件监听器,该函数不会起任何作用。

如果一个 EventTarget 上的事件监听器在另一监听器处理该事件时被移除,那么它将不能被事件触发。不过,它可以被重新绑定。

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

还有一种移除事件监听器的方法:可以向 addEventListener() 传入一个 AbortSignal,稍后再调用拥有该事件的控制器上的 abort() 方法即可。

语法

js
removeEventListener(type, listener);
removeEventListener(type, listener, options);
removeEventListener(type, listener, useCapture);

参数

type

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

listener

需要从目标事件移除的事件监听器函数。

options 可选

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

  • capture: 一个布尔值,指定需要移除的事件监听器函数是否为捕获监听器。如果未指定此参数,默认值为 false
useCapture 可选

一个布尔值,指定需要移除的事件监听器函数是否为捕获监听器。如果未指定此参数,默认值为 false

返回值

无(undefined)。

匹配要删除的事件监听器

假设你之前通过 addEventListener() 添加了一个事件监听器,你总会在某些情况下需要将其移除。很明显,你需要提供相同的 typelistener 参数给 removeEventListener(),但是 options 或者 useCapture 参数呢?

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

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

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

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

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

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

现在再思考下这个:

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

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

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

js
element.removeEventListener("mousedown", handleMouseDown, { passive: true }); // 成功
element.removeEventListener("mousedown", handleMouseDown, { capture: false }); // 成功
element.removeEventListener("mousedown", handleMouseDown, { capture: true }); // 失败
element.removeEventListener("mousedown", handleMouseDown, { passive: false }); // 成功
element.removeEventListener("mousedown", handleMouseDown, false); // 成功
element.removeEventListener("mousedown", handleMouseDown, true); // 失败

值得注意的是,一些浏览器版本在这方面会有些不一致。除非你有特别的理由,使用与调用 addEventListener() 时配置的参数去调用 removeEventListener() 是明智的。

示例

以下例子展示了添加与删除监听事件:

js
const body = document.querySelector("body");
const clickTarget = document.getElementById("click-target");
const mouseOverTarget = document.getElementById("mouse-over-target");

let toggle = false;
function makeBackgroundYellow() {
  body.style.backgroundColor = toggle ? "white" : "yellow";

  toggle = !toggle;
}

clickTarget.addEventListener("click", makeBackgroundYellow, false);

mouseOverTarget.addEventListener("mouseover", () => {
  clickTarget.removeEventListener("click", makeBackgroundYellow, false);
});

规范

Specification
DOM Standard
# ref-for-dom-eventtarget-removeeventlistener②

浏览器兼容性

BCD tables only load in the browser

参见