Удалить все прослушиватели событий определенного типа


Я хочу, чтобы удалить все прослушиватели событий определенного типа, которые были добавлены с помощью addEventListener(). Все ресурсы, которые я вижу, говорят, что вам нужно сделать это:

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

но я хочу быть в состоянии очистить его, не зная, что это в настоящее время, как это:

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

7 ответов:

это невозможно без перехвата addEventListener вызовы и отслеживать слушателей или использовать библиотеку, которая позволяет такие функции, к сожалению. Это было бы, если бы коллекция слушателей была доступна, но функция не была реализована.

самое близкое, что вы можете сделать, это удалить все прослушиватели путем клонирования элемента, который не будет клонировать коллекцию listeners.

Примечание: это также удалит слушателей на элементе дети.

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

el.parentNode.replaceChild(elClone, el);

Если ваша единственная цель, удалив прослушиватели, чтобы остановить их от запуска, вы можете добавить прослушиватель событий в окно захвата и отмены всех событий данного типа:

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

, проходящей в true для третьего параметра вызывает событие, которое будет захвачено на пути вниз. Остановка распространения означает, что событие никогда не достигает слушателей, которые его слушают.

Я знаю, что это старый, но у меня была аналогичная проблема без реальных ответов, где я хотел удалить все прослушиватели событий "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>

вы можете также перезаписать ' yourElement.метод addEventListener () и использовать.применить () ' метод для выполнения прослушивателя, как обычно, но перехват функции в процессе. Например:

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

этот скрипт должен быть запущен при загрузке страницы, иначе он не сможет перехватить все прослушиватели событий.

убедитесь в том, чтобы удалить removeListeners 'вызов () перед использованием.

удалить все прослушиватели в элементе по одна строка js:

element.parentNode.innerHTML += '';

необходимо переопределить EventTarget.прототип.addEventListener, чтобы построить функцию ловушки для входа все добавить вызовы слушателя. Что-то вроде этого:

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.прототип.removeEventListeners:

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

в крайнем случае не зная, какой обратный вызов прикреплен к прослушивателю окна, обработчик может быть оболочкой вокруг окна 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]);
}