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

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

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

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

当前回答

因此,这个函数将删除元素上的大部分指定侦听器类型:

function removeListenersFromElement(element, listenerType){
  const listeners = getEventListeners(element)[listenerType];
  let l = listeners.length;
  for(let i = l-1; i >=0; i--){
    removeEventListener(listenerType, listeners[i].listener);
  }
 }

有一些罕见的例外,其中一个不能删除的原因。

其他回答

如果不拦截addEventListener调用并跟踪侦听器,或者使用允许这些功能的库,这是不可能的。如果监听器集合是可访问的,但没有实现该特性,则会出现这种情况。

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

注意:这也会删除element子元素上的监听器。

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

el.parentNode.replaceChild(elClone, el);

删除全局事件上的所有侦听器

element.onmousedown = null;

现在您可以返回到通过添加事件侦听器

element.addEventListener('mousedown', handler, ...);

此解决方案仅适用于“全局”事件。自定义事件不起作用。以下是全球活动列表:https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers

我知道这是旧的,但我有一个类似的问题,没有真正的答案,我想从文档中删除所有按键事件侦听器。我没有删除它们,而是重写addEventListener,在添加它们之前忽略它们,类似于tom上面的回答,在加载任何其他脚本之前添加这个:

<script type="text/javascript">
    var current = document.addEventListener;
    document.addEventListener = function (type, listener) {
        if(type =="keydown")
        {
            //do nothing
        }
        else
        {
            var args = [];
            args[0] = type;
            args[1] = listener;
            current.apply(this, args);
        }
    };
</script>

在不知道哪个回调附加到窗口监听器的极端情况下,处理程序可以包装窗口addEventListener,变量可以存储监听器,以通过removeAllEventListener('scroll')正确删除每个监听器。

var listeners = {};

var originalEventListener = window.addEventListener;
window.addEventListener = function(type, fn, options) {
    if (!listeners[type])
        listeners[type] = [];

    listeners[type].push(fn);
    return originalEventListener(type, fn, options);
}

var removeAllEventListener = function(type) {
    if (!listeners[type] || !listeners[type].length)
        return;

    for (let i = 0; i < listeners[type].length; i++)
        window.removeEventListener(type, listeners[type][i]);
}

如果你删除监听器的唯一目的是阻止它们运行,你可以在窗口中添加一个事件监听器,捕捉并取消给定类型的所有事件:

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
});

但是,请注意,这可能不适用于快速事件(如mouemove),因为事件的重新分派会引入延迟。

如果您需要这样做,最好的方法是首先跟踪添加的侦听器,正如Martin Wantke的回答中所概述的那样。