JavaScript removeEventListener() 简介
在 JavaScript 中,当我们使用 addEventListener() 为一个元素添加了事件监听器后,这个监听器会一直存在。除非我们手动移除该事件监听器,或者手动从 DOM 中移除所操作的元素。
在某些情况下,我们可能不再需要某个事件监听器继续工作,例如当某个功能不再激活时,或者为了避免内存泄漏(尤其是在单页应用中)。这时就需要主动去 “取消” 该事件了。
在 JavaScript 中,我们可以使用 removeEventListener() 方法来移除之前使用 addEventListener() 附加到元素上的事件(或事件监听器)。
语法:
element.removeEventListener(event, handler, options);说明:
removeEventListener() 方法接收以下 3 个参数。
event(必选):是一个字符串,表示要移除的事件类型。比如点击事件是 "click",鼠标移入事件是 "mouseover"。注意,这个事件类型是不需要加上 “on” 前缀的。handler(必选):是一个函数名。它只能是一个具名函数,并且该函数与 addEventListener() 使用的函数名一致。options(可选):是一个对象,用于配置事件监听器的行为。该对象也必须与 addEventListener() 使用的 options 参数(特别是 capture 属性)完全相同。
注意: removeEventListener() 方法只能移除通过 addEventListener() 添加的事件,而无法移除通过事件属性方式(如 onclick)添加的事件。如果想要移除通过事件属性方式添加的事件,可以将一个 null 值赋值给对应事件属性,比如 oBtn.onclick = null;。
如何正确使用 removeEventListener()?
在 JavaScript 中,想要正确使用 removeEventListener() ,最重要的一点就是:传递给 removeEventListener() 的 handler 和 options 参数,必须与调用 addEventListener() 时使用的具有相同的引用。
1. 必须使用具名函数或函数变量
如果我们使用匿名函数直接作为处理程序传递给 addEventListener(),此时是无法通过 removeEventListener() 来移除它。这是因为每次 addEventListener() 创建匿名函数时都会生成一个新的函数引用,而 removeEventListener() 无法正确识别要移除的是哪一个事件处理程序。
示例 1:使用匿名函数无法移除监听器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button id="btn">欢迎</button>
<script>
const oBtn = document.getElementById("btn");
// 添加事件
oBtn.addEventListener("click", function() {
alert("欢迎来到绿叶网!");
});
// 移除事件
oBtn.removeEventListener("click", function() {
alert("欢迎来到绿叶网!");
});
</script>
</body>
</html>运行之后,页面效果如下图 1 所示。当点击【欢迎】按钮之后,会弹出一个对话框,如下图 2 所示。


分析:
咦,怎么回事呢?为什么我点击按钮,还会弹出对话框?上面不是已经使用 removeEventListener() 来移除 click 事件了吗?
前面已经说过,如果想要移除对应的事件处理程序,我们是不能使用匿名函数,而必须要将逻辑定义到一个 “具有名字” 的函数中去。这样 removeEventListener() 才能正确判断的是移除哪一个函数。请看下面例子。
示例 2:使用具名函数添加和移除监听器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button id="btn">欢迎</button>
<script>
function welcome() {
alert("欢迎来到绿叶网!");
}
const oBtn = document.getElementById("btn");
// 添加事件
oBtn.addEventListener("click", welcome);
// 移除事件
oBtn.removeEventListener("click", welcome);
</script>
</body>
</html>运行之后,页面效果如下图所示。当我们再次点击【欢迎】按钮之后,会发现不再弹出对话框了。

分析:
在这个例子中,虽然我们首先使用 oBtn.addEventListener("click", welcome); 为 oBtn 添加了一个 click 事件,该事件处理程序是一个名为 welcome 的函数。但在后面,我们使用了 oBtn.removeEventListener("click", welcome); 移除了同名的事件处理函数,这样就正确移除了对应的事件。
2. options 参数也必须完全相同
此外还需要注意的是,如果 addEventListener() 使用了 options 参数(例如 { capture: true }),那么在使用 removeEventListener() 移除时也必须提供完全相同的 options 对象。
示例 3:移除带 options 的监听器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<button id="btn">欢迎</button>
<script>
function welcome() {
alert("欢迎来到绿叶网!");
}
const oBtn = document.getElementById("btn");
// 添加事件
oBtn.addEventListener("click", welcome, { capture: true });
// 移除事件
oBtn.removeEventListener("click", welcome);
</script>
</body>
</html>运行之后,页面效果如下图 1 所示。当点击【欢迎】按钮之后,会弹出一个对话框,如下图 2 所示。


分析:
在移除监听器时,除了提供事件类型和函数引用外,还必须提供与添加时相同的 { capture: true } 选项对象,才能成功移除在捕获阶段注册的监听器。
因此对于这个例子来说,我们需要将 oBtn.removeEventListener("click", welcome); 修改为下面代码,这样才能正确移除对应事件。
oBtn.removeEventListener("click", welcome, { capture: true });