Müssen JavaScript-Ereignis-Listener vor dem Entfernen des Elements, an das sie angehängt sind, entfernt werden?

8

Angenommen, ich habe verschiedene Ereignis-Listener an verschiedene Formularelemente angehängt. Später möchte ich das gesamte Formular entfernen.

Ist es erforderlich (oder vorgeschlagen), Event-Handler, die auf dem Formular und seinen Elementen vorhanden sind, aufzuheben? Wenn ja, was ist der einfachste Weg, um alle Listener einer Sammlung von Elementen zu entfernen? Was sind die Auswirkungen davon, dies nicht zu tun? Ich benutze Prototyp, wenn es darauf ankommt.

Folgendes mache ich eigentlich. Ich habe eine einfache Form, so:

%Vor%

Ich beobachte verschiedene Ereignisse an den Eingängen, z. B .:

%Vor%

usw.

Das Formular wird über AJAX gesendet und die Antwort ist eine neue Kopie des Formulars. Ich ersetze das alte Formular durch eine Kopie des neuen Formulars, indem ich etwas wie $('form').replace(newForm) mache. Sammle ich einen Haufen Event Craft?

    
Jeremy Kauffman 16.07.2009, 15:52
quelle

3 Antworten

3

Ja, ein bisschen. Nicht genug, um ein riesiges Problem zu sein, aber ältere Versionen von IE werden unter diesen Umständen auslaufen.

Seit Prototype 1.6.1 (derzeit in seinem endgültigen Veröffentlichungskandidaten) behandelt die Bibliothek diese Bereinigung beim Entladen der Seite. Wenn Sie mit Prototype einen Ereignisbeobachter hinzufügen, behält es einen Verweis auf dieses Element in einem Array bei. Beim Entladen der Seite durchläuft es dieses Array und entfernt alle Ihre Beobachter.

Wenn der Benutzer jedoch eine Weile auf dieser Seite bleibt, wird die Speicherauslastung über die Lebensdauer der Seite hinweg zunehmen. Sie haben mehrere Möglichkeiten:

  1. Achten Sie auf Ereignisse auf einem Vorgänger des Formulars, das niemals ersetzt wird. Überprüfen Sie dann in Ihrem Handler, woher das Ereignis stammt. (d. h. "Ereignisdelegierung")

  2. Melden Sie explizit alle Ihre Anrufe ab, bevor Sie Element#replace aufrufen. In Ihrem Beispiel würden Sie tun:

    %Vor%

Dies entspricht dem Aufruf von stopObserving ohne Argumente, was dazu führt, dass alle Handler für ein bestimmtes Element entfernt werden.

Ich würde Option 1 empfehlen.

(Wir haben darüber gesprochen, die automatische Entfernung von Listenern in einer zukünftigen Version von Prototype als Teil von Element#update und Element#replace auszuführen, aber es handelt sich um einen Leistungskonflikt.)

    
savetheclocktower 27.07.2009, 18:22
quelle
4

Ereignisse, die nicht nicht registriert sind, können ihren Speicher nicht automatisch freigeben. Dies ist insbesondere ein Problem in älteren Versionen von IE.

Prototyp hatte dafür ein automatisches Speicherbereinigungssystem, aber die Methode wurde in Version 1.6 entfernt. Es ist dokumentiert hier . Ob die Entfernung der Methode bedeutet, dass die Garbage Collection nicht mehr stattfindet oder die Methode einfach nicht mehr öffentlich verfügbar ist, weiß ich nicht. Beachten Sie außerdem, dass es immer nur beim Entladen der Seite aufgerufen wurde. Wenn Ihre Benutzer lange auf der gleichen Seite bleiben, während viele AJAX- und DOM-Aktualisierungen durchgeführt werden, kann der Speicher sogar während dieser einen Seite zu einem unakzeptablen Ausmaß führen.

    
Jonas H 16.07.2009 16:19
quelle
0

Es ist immer gut, Event-Listener von Elementen zu entfernen, die aus dem DOM entfernt wurden, falls das Szenario Jonas unten erwähnt wird.

    
Lark 16.07.2009 16:34
quelle