web-dev-qa-db-fra.com

Supprimer tous les écouteurs d'événement d'un type spécifique

Je souhaite supprimer tous les écouteurs d'événements d'un type spécifique ajoutés à l'aide de addEventListener(). Toutes les ressources que je vois disent que vous devez faire ceci:

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

Mais je veux pouvoir l'effacer sans savoir ce que c'est actuellement, comme ceci:

elem.addEventListener('mousedown',specific_function);
elem.removeEventListener('mousedown');
91
J S

Cela n'est pas possible sans intercepter les appels addEventListener et garder une trace des auditeurs ou utiliser une bibliothèque qui permet malheureusement de telles fonctionnalités. Cela aurait été le cas si la collection d'écouteurs était accessible mais que la fonctionnalité n'était pas implémentée .

La chose la plus proche que vous puissiez faire est de supprimer tous les écouteurs en clonant l'élément, ce qui ne clonera pas la collection d'écouteurs.

Note: Ceci supprimera également les écouteurs sur les enfants de l'élément.

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

el.parentNode.replaceChild(elClone, el);
179
plalx

Si votre seul objectif en supprimant les écouteurs est de les empêcher de s'exécuter, vous pouvez ajouter un écouteur d'événements à la fenêtre en capturant et en annulant tous les événements du type donné:

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

Passer true pour le troisième paramètre provoque la capture de l'événement en descendant. Arrêter la propagation signifie que l’événement n’atteint jamais les auditeurs qui l’écoutent.

15
Chris Middleton

Je sais que c'est vieux, mais j'avais un problème similaire, sans vraies réponses, dans lequel je voulais supprimer tous les écouteurs d'événements "keydown" du document. Au lieu de les supprimer, j'ai redéfini addEventListener pour les ignorer avant même de les ajouter, comme dans la réponse de Toms ci-dessus, en ajoutant ceci avant le chargement d'autres scripts:

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

Vous pouvez également écraser la méthode 'yourElement.addEventListener ()' et utiliser la méthode '.apply ()' pour exécuter l'écouteur normalement, mais en interceptant la fonction dans le processus. Comme:

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

Ce script doit être exécuté au chargement de la page ou il risque de ne pas intercepter tous les écouteurs d'événement.

Assurez-vous de supprimer l'appel 'removeListeners ()' avant de l'utiliser.

1
Tom Burris

Vous devez remplacer EventTarget.prototype.addEventListener pour créer une fonction d'interruption permettant de consigner tous les appels 'add listener'. Quelque chose comme ça:

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

Ensuite, vous pouvez créer un 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);
        }
    }
}

Dans ES6, vous pouvez utiliser un symbole pour masquer la fonction d'origine et la liste de tous les écouteurs ajoutés directement dans l'objet auto-instancié.

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

Vous pouvez tester ce code avec ce petit snipper:

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
0
Martin Wantke

Dans le cas extrême de ne pas savoir quel rappel est attaché à un écouteur de fenêtre, un gestionnaire peut encapsuler une fenêtre addEventListener et une variable peut stocker tous les écouteurs pour supprimer correctement chacun de ceux-ci via removeAllEventListener('scroll') par exemple.

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]);
}
0
yves amsellem

Supprimer tous les écouteurs de l'élément par une ligne js

element.parentNode.innerHTML += '';
0
Nazar Vynnytskyi
 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)
}
0
Sri Harsha