删除特定类型的所有事件侦听器

2022-08-30 01:10:26

我想删除使用 添加的所有特定类型的事件侦听器。我看到的所有资源都说你需要这样做:addEventListener()

elem.addEventListener('mousedown',specific_function);
elem.removeEventListener('mousedown',specific_function);

但是我希望能够在不知道它当前是什么的情况下清除它,就像这样:

elem.addEventListener('mousedown',specific_function);
elem.removeEventListener('mousedown');

答案 1

如果不拦截调用并跟踪侦听器或使用允许此类功能的库,这是不可能的。如果侦听器集合是可访问的,但该功能未实现,则会是这样。addEventListener

您可以做的最接近的事情是通过克隆元素来删除所有侦听器,这不会克隆侦听器集合。

注意:这还将删除元素子元素上的侦听器。

var el = document.getElementById('el-id'),
    elClone = el.cloneNode(true);

el.parentNode.replaceChild(elClone, el);

答案 2

如果删除侦听器的唯一目标是阻止它们运行,则可以向窗口添加一个事件侦听器,捕获并取消给定类型的所有事件:

window.addEventListener(type, function(event) {
    event.stopImmediatePropagation();
}, true);

传入第三个参数会导致在向下传递的过程中捕获事件。停止传播意味着事件永远不会到达正在侦听它的侦听器。true

请记住,这具有非常有限的用途,因为您无法为给定类型添加新的侦听器(它们都将被阻止)。有一些方法可以解决这个问题,例如,通过触发一种只有你的听众才会知道要听的新型事件。以下是您可以执行的操作:

window.addEventListener('click', function (event) {
    // (note: not cross-browser)
    var event2 = new CustomEvent('click2', {detail: {original: event}});
    event.target.dispatchEvent(event2);
    event.stopPropagation();
}, true);

element.addEventListener('click2', function(event) {
    if (event.detail && event.detail.original) {
        event = event.detail.original
    }
    // Do something with event
});

但是,请注意,这可能不适用于像 mousemove 这样的快速事件,因为事件的重新调度会引入延迟。

更好的做法是跟踪首先添加的听众,如Martin Wantke的答案中所述,如果您需要这样做的话。