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

时间:2013-10-19 19:03:56

标签: javascript events

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

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

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

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

11 个答案:

答案 0 :(得分:187)

如果不拦截addEventListener调用并跟踪侦听器或使用不幸允许此类功能的库,则无法实现。如果听众集合可以访问,那就是feature wasn't implemented

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

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

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

el.parentNode.replaceChild(elClone, el);

答案 1 :(得分:20)

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

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

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

答案 2 :(得分:5)

我知道这已经过时了,但我遇到了类似的问题但没有真正的答案,我想从文档中删除所有“keydown”事件监听器。我没有删除它们,而是覆盖addEventListener以在它们被添加之前忽略它们,类似于上面的Toms回答,通过在加载任何其他脚本之前添加它。:

<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>

答案 3 :(得分:2)

因此,此函数摆脱了元素上大多数指定的侦听器类型:

iterationCount

有一些罕见的例外,由于某种原因而无法将其删除。

答案 4 :(得分:2)

快速而肮脏的方式

element.onmousedown = null;

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

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

答案 5 :(得分:1)

您也可以覆盖&#39; yourElement.addEventListener()&#39;方法并使用&#39; .apply()&#39;像正常一样执行监听器的方法,但是拦截过程中的函数。像:

<script type="text/javascript">

    var args = [];
    var orginalAddEvent = yourElement.addEventListener;

    yourElement.addEventListener = function() {
        //console.log(arguments);
        args[args.length] = arguments[0];
        args[args.length] = arguments[1];
        orginalAddEvent.apply(this, arguments);
    };

    function removeListeners() {
        for(var n=0;n<args.length;n+=2) {
            yourElement.removeEventListener(args[n], args[n+1]);
        }
    }

    removeListeners();

</script>

此脚本必须在页面加载时运行,否则它可能不会拦截所有事件侦听器。

请务必删除&#39; removeListeners()&#39;使用前打电话。

答案 6 :(得分:1)

删除元素中的所有侦听器 one js line

// assuming you already have an authenticated SDK in the variable podio

const onNotificationReceived = (message) => {
  console.log(message);
};

const subscribeToPushNotifications = (itemId) => {

  podio.request('GET', `/item/${itemId}`).then((data) => {
    podio.push(data.push).subscribe(this.onNotificationReceived)
      .then(() => console.log(`All is well, we've been subscribed!`));
  }).catch(err => { 
    throw new Error(err) 
  });

};

// Whatever item you want to receive notifications about
const itemId = 99999999;

subscribeToPushNotifications(itemId);

答案 7 :(得分:1)

您必须重写EventTarget.prototype.addEventListener以构建一个陷阱函数,用于记录所有&#39;添加侦听器&#39;调用。像这样:

var _listeners = [];

EventTarget.prototype.addEventListenerBase = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(type, listener)
{
    _listeners.push({target: this, type: type, listener: listener});
    this.addEventListenerBase(type, listener);
};

然后你可以构建一个EventTarget.prototype.removeEventListener s

EventTarget.prototype.removeEventListeners = function(targetType)
{
    for(var index = 0; index != _listeners.length; index++)
    {
        var item = _listeners[index];

        var target = item.target;
        var type = item.type;
        var listener = item.listener;

        if(target == this && type == targetType)
        {
            this.removeEventListener(type, listener);
        }
    }
}

在ES6中,您可以使用符号,直接在实例化的对象self中隐藏原始函数和所有添加的侦听器的列表。

(function()
{
    let target = EventTarget.prototype;
    let functionName = 'addEventListener';
    let func = target[functionName];

    let symbolHidden = Symbol('hidden');

    function hidden(instance)
    {
        if(instance[symbolHidden] === undefined)
        {
            let area = {};
            instance[symbolHidden] = area;
            return area;
        }

        return instance[symbolHidden];
    }

    function listenersFrom(instance)
    {
        let area = hidden(instance);
        if(!area.listeners) { area.listeners = []; }
        return area.listeners;
    }

    target[functionName] = function(type, listener)
    {
        let listeners = listenersFrom(this);

        listeners.push({ type, listener });

        func.apply(this, [type, listener]);
    };

    target['removeEventListeners'] = function(targetType)
    {
        let self = this;

        let listeners = listenersFrom(this);
        let removed = [];

        listeners.forEach(item =>
        {
            let type = item.type;
            let listener = item.listener;

            if(type == targetType)
            {
                self.removeEventListener(type, listener);
            }
        });
    };
})();

您可以使用这个小片段来测试此代码:

document.addEventListener("DOMContentLoaded", event => { console.log('event 1'); });
document.addEventListener("DOMContentLoaded", event => { console.log('event 2'); });
document.addEventListener("click", event => { console.log('click event'); });

document.dispatchEvent(new Event('DOMContentLoaded'));
document.removeEventListeners('DOMContentLoaded');
document.dispatchEvent(new Event('DOMContentLoaded'));
// click event still works, just do a click in the browser

答案 8 :(得分:0)

在不知道哪个回调附加到窗口侦听器的极端情况下,处理程序可以包装在窗口addEventListener周围,并且变量可以存储永远的侦听器以通过{{1}正确地删除每个回调器例如。

removeAllEventListener('scroll')

答案 9 :(得分:0)

 var events = [event_1, event_2,event_3]  // your events

//make a for loop of your events and remove them all in a single instance

 for (let i in events){
    canvas_1.removeEventListener("mousedown", events[i], false)
}

答案 10 :(得分:0)

您无法删除单个事件,但可以删除所有事件吗?立刻?只需

document.body.innerHTML = document.body.innerHTML