ZetCode

JavaScript removeEventListener

最后修改于 2025 年 4 月 2 日

在本文中,我们将探讨 JavaScript 中的 removeEventListener 方法。此方法对于正确的事件处理至关重要,它允许开发人员在不再需要事件监听器时进行清理。

基本定义

removeEventListener 方法会移除先前使用 addEventListener 注册的事件监听器。它需要与添加监听器时使用的参数完全相同,以便正确地识别和移除它。

要成功移除,事件类型、监听器函数和选项/捕获标志必须与 addEventListener 中使用的完全匹配。匿名函数无法移除,因为它们每次都会创建新的函数实例。

基本的 removeEventListener

本示例演示了如何添加然后移除一个简单的点击事件监听器。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Basic removeEventListener</title>
</head>
<body>

<button id="myBtn">Click Me</button>
<button id="removeBtn">Remove Listener</button>

<script>
    const button = document.getElementById('myBtn');
    const removeButton = document.getElementById('removeBtn');
    
    function handleClick() {
        console.log('Button was clicked!');
    }
    
    button.addEventListener('click', handleClick);
    
    removeButton.addEventListener('click', function() {
        button.removeEventListener('click', handleClick);
        console.log('Listener removed!');
    });
</script>

</body>
</html>

在此示例中,我们首先使用一个命名函数向按钮添加一个点击事件监听器。然后,我们提供第二个按钮,点击该按钮将移除此监听器。

这演示了 removeEventListener 的基本用法。添加和移除监听器必须使用相同的函数引用。

移除匿名函数

本示例展示了为什么匿名函数无法被移除,以及如何解决此限制。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Anonymous Functions</title>
</head>
<body>

<button id="myBtn">Click Me</button>
<button id="removeBtn">Try to Remove</button>

<script>
    const button = document.getElementById('myBtn');
    const removeButton = document.getElementById('removeBtn');
    
    // Adding anonymous function
    button.addEventListener('click', function() {
        console.log('Anonymous function called');
    });
    
    removeButton.addEventListener('click', function() {
        // This won't work!
        button.removeEventListener('click', function() {
            console.log('Anonymous function called');
        });
        console.log('Attempted to remove listener');
    });
</script>

</body>
</html>

这里我们尝试移除一个匿名函数事件监听器。移除失败,因为 removeEventListener 中的函数与 addEventListener 中使用的函数不是同一个实例。

这凸显了为什么当你以后需要移除监听器时,命名函数是首选。每个匿名函数都会在内存中创建一个新对象。

使用选项移除

本示例演示了如何正确移除带有特定选项添加的事件监听器。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Removing with Options</title>
</head>
<body>

<div id="myDiv" style="padding: 20px; background: #eee;">
    <p>Click anywhere in this box</p>
</div>
<button id="removeBtn">Remove Listener</button>

<script>
    const div = document.getElementById('myDiv');
    const removeButton = document.getElementById('removeBtn');
    
    function handleClick() {
        console.log('Div was clicked (capturing phase)');
    }
    
    // Add with capture option
    div.addEventListener('click', handleClick, { capture: true });
    
    removeButton.addEventListener('click', function() {
        // Must specify same options for removal
        div.removeEventListener('click', handleClick, { capture: true });
        console.log('Listener with options removed');
    });
</script>

</body>
</html>

在此示例中,我们添加了一个 capture 选项设置为 true 的事件监听器。要移除它,我们必须提供相同的选项对象。

选项参数必须完全匹配。如果你使用选项添加,则必须使用相同的选项移除。这同样适用于所有选项,例如 oncepassive

多个监听器

本示例展示了如何管理多个事件监听器并选择性地移除它们。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Multiple Listeners</title>
</head>
<body>

<button id="myBtn">Click Me</button>
<button id="removeFirstBtn">Remove First</button>
<button id="removeSecondBtn">Remove Second</button>

<script>
    const button = document.getElementById('myBtn');
    const removeFirstBtn = document.getElementById('removeFirstBtn');
    const removeSecondBtn = document.getElementById('removeSecondBtn');
    
    function firstListener() {
        console.log('First listener called');
    }
    
    function secondListener() {
        console.log('Second listener called');
    }
    
    button.addEventListener('click', firstListener);
    button.addEventListener('click', secondListener);
    
    removeFirstBtn.addEventListener('click', function() {
        button.removeEventListener('click', firstListener);
        console.log('First listener removed');
    });
    
    removeSecondBtn.addEventListener('click', function() {
        button.removeEventListener('click', secondListener);
        console.log('Second listener removed');
    });
</script>

</body>
</html>

在这里,我们向同一个按钮添加了两个独立的点击事件监听器。然后,我们提供按钮来单独移除每个监听器。

这演示了 removeEventListener 如何定位特定的监听器,同时保留其他监听器。每个监听器函数在事件系统中都保持其自身的身份。

一次性选项的替代方案

本示例展示了如何使用 removeEventListener 手动实现 once 选项的行为。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Once Option Alternative</title>
</head>
<body>

<button id="myBtn">Click Me Once</button>

<script>
    const button = document.getElementById('myBtn');
    
    function handleClickOnce(event) {
        console.log('This will only log once');
        event.target.removeEventListener('click', handleClickOnce);
    }
    
    button.addEventListener('click', handleClickOnce);
</script>

</body>
</html>

在此示例中,我们创建了一个自移除事件监听器。第一次点击后,监听器会从元素中移除自身。

当您需要比 once 选项更多的控制,或者需要支持不支持 once 选项的旧浏览器时,这种模式非常有用。

来源

MDN removeEventListener 文档

在本文中,我们展示了如何在 JavaScript 中使用 removeEventListener。正确的监听器清理对于内存管理和防止 Web 应用程序中意外行为至关重要。

作者

我叫 Jan Bodnar,是一名充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有超过十年的经验。

列出 所有 JS DOM 教程