wake-up-neo.com

Javascript/DOM: Wie entferne ich alle Ereignisse eines DOM-Objekts?

Nur eine Frage: Gibt es eine Möglichkeit, alle Ereignisse eines Objekts vollständig zu entfernen, z. ein div?

BEARBEITEN: Ich füge pro div.addEventListener('click',eventReturner(),false); ein Ereignis hinzu.

function eventReturner() {
    return function() {
        dosomething();
    };
}

EDIT2: Ich habe einen Weg gefunden, der funktioniert, aber nicht für meinen Fall verwendet werden kann:

var returnedFunction;
function addit() {
    var div = document.getElementById('div');
    returnedFunction = eventReturner();
    div.addEventListener('click',returnedFunction,false); //You HAVE to take here a var and not the direct call to eventReturner(), because the function address must be the same, and it would change, if the function was called again.
}
function removeit() {
    var div = document.getElementById('div');
    div.removeEventListener('click',returnedFunction,false);
}
58
Florian Müller

Ich bin nicht sicher, was Sie mit alle Events} meinen. Alle Handler für einen bestimmten Ereignistyp oder alle Ereignishandler für einen Typ entfernen?

Entfernen Sie alle Ereignishandler

Wenn Sie alle Event-Handler (eines beliebigen Typs) entfernen möchten, können Sie Klon das Element verwenden und durch seinen Klon ersetzen:

var clone = element.cloneNode(true);

Note: Dadurch werden Attribute und untergeordnete Elemente beibehalten, jedoch keine Änderungen an den DOM-Eigenschaften.


Entfernen Sie "anonyme" Ereignishandler eines bestimmten Typs

Die andere Möglichkeit ist die Verwendung von removeEventListener() , aber ich denke, Sie haben dies bereits versucht und es hat nicht funktioniert. Hier ist der Haken :

Durch Aufruf von addEventListener an eine anonyme Funktion wird jedes Mal ein neuer Listener erstellt. Das Aufrufen von removeEventListener auf eine anonyme Funktion hat keine Auswirkung. Eine anonyme Funktion erstellt bei jedem Aufruf ein eindeutiges Objekt. Es handelt sich nicht um einen Verweis auf ein vorhandenes Objekt. Es kann jedoch auch ein Objekt aufgerufen werden. Wenn Sie einen Ereignis-Listener auf diese Weise hinzufügen, stellen Sie sicher, dass er nur einmal hinzugefügt wird. Er ist dauerhaft (kann nicht entfernt werden), bis das Objekt, zu dem er hinzugefügt wurde, zerstört wird.

Sie übergeben im Wesentlichen eine anonyme Funktion an addEventListener, da eventReturner eine Funktion zurückgibt.

Sie müssen Möglichkeiten haben, um dieses Problem zu lösen:

  1. Verwenden Sie keine Funktion, die eine Funktion zurückgibt. Nutzen Sie die Funktion direkt:

    function handler() {
        dosomething();
    }
    
    div.addEventListener('click',handler,false);
    
  2. Erstellen Sie einen Wrapper für addEventListener, der einen Verweis auf die zurückgegebene Funktion speichert, und erstellen Sie eine seltsame removeAllEvents-Funktion:

    var _eventHandlers = {}; // somewhere global
    
    function addListener(node, event, handler, capture) {
        if(!(node in _eventHandlers)) {
            // _eventHandlers stores references to nodes
            _eventHandlers[node] = {};
        }
        if(!(event in _eventHandlers[node])) {
            // each entry contains another entry for each event type
            _eventHandlers[node][event] = [];
        }
        // capture reference
        _eventHandlers[node][event].Push([handler, capture]);
        node.addEventListener(event, handler, capture);
     }
    
    function removeAllListeners(node, event) {
        if(node in _eventHandlers) {
            var handlers = _eventHandlers[node];
            if(event in handlers) {
                var eventHandlers = handlers[event];
                for(var i = eventHandlers.length; i--;) {
                    var handler = eventHandlers[i];
                    node.removeEventListener(event, handler[0], handler[1]);
                }
            }
        }
    }
    

    Und dann könntest du es verwenden mit:

    addListener(div, 'click', eventReturner(), false)
    // and later
    removeListeners(div, 'click')
    

DEMO

Hinweis: Wenn Ihr Code längere Zeit ausgeführt wird und Sie viele Elemente erstellen und entfernen, müssen Sie sicherstellen, dass Sie die in _eventHandlers enthaltenen Elemente entfernen, wenn Sie sie löschen.

73
Felix Kling

Verwenden Sie die eigene Funktion des Ereignis-Listeners remove(). Zum Beispiel:

getEventListeners().click.forEach((e)=>{e.remove()})
25
JuanGG

Dadurch werden alle Listener von Kindern entfernt, bei großen Seiten jedoch langsam. Brutal einfach zu schreiben.

element.outerHTML = element.outerHTML;
13
pabombs

Wie corwin.amber sagt, gibt es Unterschiede zwischen Webkit und anderen.

In Chrome:

getEventListeners(document);

Welches gibt Ihnen ein Objekt mit allen vorhandenen Ereignis-Listenern:

Object 
 click: Array[1]
 closePopups: Array[1]
 keyup: Array[1]
 mouseout: Array[1]
 mouseover: Array[1]
 ...

Von hier aus erreichen Sie den Listener, den Sie entfernen möchten:

getEventListeners(document).copy[0].remove();

Also alle Event-Hörer:

for(var eventType in getEventListeners(document)) {
   getEventListeners(document)[eventType].forEach(
      function(o) { o.remove(); }
   ) 
}

In Firefox

Ist ein wenig anders, da ein Listener-Wrapper verwendet wird, der keine Remove-Funktion enthält. Sie müssen den Listener erhalten, den Sie entfernen möchten:

document.removeEventListener("copy", getEventListeners(document).copy[0].listener)

Alle Zuhörer der Veranstaltung:

for(var eventType in getEventListeners(document)) {
  getEventListeners(document)[eventType].forEach(
    function(o) { document.removeEventListener(eventType, o.listener) }
  ) 
}

Ich stolperte über diesen Beitrag und versuchte, den lästigen Kopierschutz einer Nachrichten-Website zu deaktivieren.

Genießen!

7
Jmakuc

Möglicherweise erledigt der Browser dies für Sie, wenn Sie Folgendes tun:

Kopieren Sie die Variable div und ihre Attribute und fügen Sie sie vor der alten ein. Verschieben Sie dann den Inhalt von der alten in die neue und löschen Sie die alte.

0
Mic

Um die Antworten zu vervollständigen, finden Sie hier Beispiele aus der Praxis zum Entfernen von Ereignissen, wenn Sie Websites besuchen und keine Kontrolle über den generierten HTML- und JavaScript-Code haben.

Einige lästige Websites verhindern, dass Sie Benutzernamen in Anmeldeformulare kopieren und einfügen. Dies kann leicht umgangen werden, wenn das Ereignis onpaste mit dem HTML-Attribut onpaste="return false" hinzugefügt wird. In diesem Fall müssen wir nur mit der rechten Maustaste auf das Eingabefeld klicken, "Element untersuchen" in einem Browser wie Firefox auswählen und das HTML-Attribut entfernen.

Wenn das Ereignis jedoch wie folgt über JavaScript hinzugefügt wurde:

document.getElementById("lyca_login_mobile_no").onpaste = function(){return false};

Wir müssen die Veranstaltung auch über JavaScript entfernen:

document.getElementById("lyca_login_mobile_no").onpaste = null;

In meinem Beispiel habe ich die ID "lyca_login_mobile_no" verwendet, da dies die Texteingabe-ID war, die von der Website verwendet wurde, die ich besuchte.

Eine andere Möglichkeit, das Ereignis zu entfernen (wodurch auch alle Ereignisse entfernt werden), besteht darin, den Knoten zu entfernen und einen neuen zu erstellen, wie wir es tun müssen, wenn addEventListener verwendet wurde, um Ereignisse mit einer anonymen Funktion hinzuzufügen, die wir nicht entfernen können mit removeEventListener. Dies kann auch über die Browserkonsole erfolgen, indem Sie ein Element untersuchen, den HTML-Code kopieren, den HTML-Code entfernen und dann den HTML-Code an derselben Stelle einfügen.

Es kann auch schneller und automatisiert über JavaScript erfolgen:

var oldNode = document.getElementById("lyca_login_mobile_no");
var newNode = oldNode.cloneNode(true);
oldNode.parentNode.insertBefore(newNode, oldNode);
oldNode.parentNode.removeChild(oldNode);

Update: Wenn die Web-App mit einem JavaScript-Framework wie Angular erstellt wurde, scheint es, dass die vorherigen Lösungen nicht funktionieren oder die App beschädigen. Eine andere Problemumgehung, um das Einfügen zu ermöglichen, besteht darin, den Wert über JavaScript festzulegen:

document.getElementById("lyca_login_mobile_no").value = "username";

Im Moment weiß ich nicht, ob es eine Möglichkeit gibt, alle Formularüberprüfungs- und Einschränkungsereignisse zu entfernen, ohne eine App zu beschädigen, die vollständig in JavaScript wie Angular geschrieben ist.

0
baptx

Nur Chrome

Während ich versuche, einen EventListener aus einem Protractor-Test zu entfernen, und keinen Zugriff auf den Listener im Test habe, funktioniert das folgende Verfahren, um alle Event-Listener eines einzigen Typs zu entfernen:

function(eventType){
    getEventListeners(window).[eventType].forEach(
        function(e){
            window.removeEventListener(eventType, e.listener)
        }
    );
}

Ich hoffe, das hilft jemandem, da die vorhergehende Antwort die "Remove" -Methode verwendet hat, die seitdem nicht mehr funktioniert.

0
Filipe Melo