Migrieren von Veränderungs- und Eigenschaftsänderungsereignissen zu Veränderungsbeobachtern

Veränderungsbeobachter in Internet Explorer 11 stellen einen leistungsfähigen Ersatz für alle entsprechenden Szenarien dar, die von Veränderungsereignissen unterstützt werden, sowie eine Alternative für die Szenarien, die von Eigenschaftsänderungsereignissen unterstützt werden.

Vorhandener Code kann mit Veränderungsereignissen und/oder Eigenschaftsänderungsereignissen zu Veränderungsbeobachtern migriert werden.

Ältere Techniken für die Überwachung von DOM-Veränderungen

Mutation events spielen bei der Webplattform eine wichtige Rolle. Mit ihnen können Web-Apps synchron dynamische Änderungen an Elementen im Dokumentobjektmodell (DOM) einer Webseite überwachen. Veränderungsereignisse sind zwar hilfreich, aber auch für ihre Beeinträchtigung der App-Leistung bekannt, die in erster Linie auf ihre synchrone Veranlagung und auf die Ereignisarchitektur zurückzuführen ist, auf deren Grundlage sie arbeiten.

Hinweis   Veränderungsereignisse (gemäß Definition in den DOM-Ereignissen der Ebene 3 des W3C) werden durch Veränderungsbeobachter (W3C DOM4) ersetzt.

Eigenschaftsänderungsereignisse weisen ein ähnliches Verhalten auf wie Veränderungsereignisse. Auch Eigenschaftsänderungsereignisse bringen eine Leistungsbeeinträchtigung mit sich; dies ist auf das Legacy-Browserereignissystem zurückzuführen, das für den ordnungsgemäßen Betrieb erforderlich ist.

Hinweis  Das onpropertychange-Ereignis wird nur vom älteren, IE-exklusiven attachEvent-Ereignisregistrierungsmodell unterstützt, das seit Windows Internet Explorer 9 als veraltet gilt (und in IE11 nicht mehr unterstützt wird). Stattdessen wird nun das addEventListener-Ereignismodell nach dem W3C-Standard verwendet.

Erkennen von Veränderungsereignissen

Die Veränderungsereignisse (verfügbar ab Internet Explorer 9) sind ganz einfach an ihrem Namen zu erkennen: Hierbei handelt es sich um einen Zeichenfolgenparameter, der an die Plattform-API addEventListener oder removeEventListener übergeben wird:

  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMSubtreeModified
  • DOMAttrModified
  • DOMCharacterDataModified

Hinweis  Durch den Standard werden noch zwei weitere Veränderungsereignisse definiert, diese werden jedoch nicht von Internet Explorer unterstützt: DOMNodeInsertedIntoDocument und DOMNodeRemovedFromDocument.

Im Folgenden finden Sie ein Beispiel, wie eines dieser Ereignisse in JavaScript-Code aussehen würde:


someElement.addEventListener("DOMAttrModified", function() {
  //...
}, false);

Die Veränderungsereignisse DOMNodeInserted, DOMNodeRemoved und DOMSubtreeModified dienen zum Überwachen struktureller Änderungen an den untergeordneten Elementen eines Elements – Elemente werden entweder hinzugefügt oder entfernt. Das DOMSubtreeModified-Ereignis gilt für beides und wird sowohl bei Entfernungs- als auch bei Hinzufügevorgängen ausgelöst. Es gibt jedoch keinen Aufschluss darüber, warum es ausgelöst wurde. Sie können also allein anhand des Ereignisses nicht unterscheiden, ob etwas hinzugefügt oder entfernt wurde.

Das Veränderungsereignis DOMAttrModified meldet Änderungen an der Attributliste eines Elements. Dieses einzelne Ereignis enthält Informationen zu Attributeinfügungen, -entfernungen oder -änderungen.

Das Veränderungsereignis DOMCharacterDataModified meldet Änderungen am Textinhalt eines Elements. Textinhalt ist in logische Einheiten (so genannte Textknoten) gruppiert, und nur Änderungen an einem vorhandenen Textknoten lösen das Ereignis DOMCharacterDataModified aus. Neu eingefügte/erstellte Textknoten werden dagegen als Ereignis vom Typ DOMNodeInserted gemeldet.

Die Suche nach Veränderungsereignissen im Code sollte einfach sein, z. B. mithilfe der Suchfunktion In Dateien suchen Ihres bevorzugten Editors. Vergessen Sie nicht, dass Variablen häufig in der addEventListener-Methode verwendet werden. Suchen Sie daher zunächst nach der Verwendung der Veränderungsereignis-Zeichenfolgen ("DOMNodeInserted", "DOMNodeRemoved" usw.), und überprüfen Sie anschließend noch mal alle Vorkommen von addEventListener, um sicherzugehen, dass Sie alle gefunden haben.

Erkennen von Eigenschaftsänderungsereignissen

Eigenschaftsänderungsereignisse sind anhand des onpropertychange-Ereignisnamens zu erkennen, der in Verbindung mit den IE-exklusiven Ereignisregistrierungs-APIs attachEvent und detachEvent verwendet wird. Suchen Sie nach allen Vorkommen von attachEvent, und überprüfen Sie den ersten Parameter auf onpropertychange, um die Verwendungen in Ihrem Code ausfindig zu machen.

Das Eigenschaftsänderungsereignis wird ausgelöst, wenn sich die Eigenschaften eines DOM-Elements ändern. Bei diesem Ereignis tritt kein Bubbling auf, und es gilt seit Internet Explorer 9 als veraltet. Ersetzt wurde es durch das addEventListener-Ereignismodell nach dem W3C-Standard. Das Ereignis enthält den Namen der geänderten Eigenschaft im propertyName-Getter des Ereignisses. Zum Verteilen eines Eigenschaftsänderungsereignisses wird leider auch eine Reihe anderer Ereignisattribute berechnet. Einige erzwingen eine Neuberechnung des Layoutmoduls, was für alle Anwendungen, die dieses Ereignis verwenden, eine deutliche Leistungsbeeinträchtigung bedeutet.

Unlike with mutation events, das Eigenschaftsänderungsereignis lässt sich nicht exakt einem Veränderungsbeobachter zuordnen. Es ist allerdings möglich, die Verwendung von Eigenschaftsänderungsereignissen durch Veränderungsbeobachter zu ersetzen, wenn sich die betroffenen Eigenschaftsnamen als HTML-Attribute wiederfinden. Beispiele: id (stellt das id-Attribut dar), style.color (findet sich im serialisierten style-Attribut wieder) und className (entspricht dem class-Attribut).

Hinweis  Für Eigenschaften, die nicht als HTML-Attribute dargestellt werden (wie value für input-Elemente) können Sie das ECMAScript 5-Feature (JavaScript) namens defineProperty verwenden. Das Migrieren von Eigenschaftsänderungsereignissen mithilfe der Object.defineProperty-JavaScript-API wird in diesem Dokument nicht beschrieben.

Unterschiede bei Veränderungsbeobachtern

Veränderungsbeobachter basieren nicht auf dem Ereignismodell der Webplattform. Dies ist ein bedeutender Unterschied, der eine deutlich schnellere Verteilung ohne Ereignis-Bubbling über die DOM-Elementhierarchie ermöglicht.

Darüber hinaus erfassen Veränderungsbeobachter mehrere Änderungen, bevor der Beobachter informiert wird. Veränderungsdatensätze werden gesammelt, um die App nicht mit Ereignissen zu überfluten. Im Gegensatz dazu sind Veränderungsereignisse synchron und führen zu einer Unterbrechung der normalen Codeausführung, um die App über Veränderungen zu informieren. Trotz des Modells mit verzögerter Benachrichtigung, das bei Veränderungsbeobachtern zur Anwendung kommt, erhält der Beobachter der App garantiert alle Veränderungsdatensätze vor der nächsten Neuzeichnung und kann sie rechtzeitig verarbeiten.

Diese Änderungen haben beide Einfluss darauf, wie Ihre App zur Unterstützung von Veränderungsbeobachtern angepasst werden muss.

Registrierung von Veränderungsbeobachtern

Veränderungsbeobachter müssen zunächst erstellt werden, damit sie für ein bestimmtes Element registriert werden können. Verwenden Sie zum Erstellen eines Veränderungsbeobachters den JavaScript-Operator new, und geben Sie eine Rückrufmethode an:


var mutationObserver = new MutationObserver(callback);

Der Rückruf, den Sie für den Veränderungsbeobachter-Konstruktor angeben, unterscheidet sich von dem Rückruf, den Sie wahrscheinlich für Ihre derzeitigen Veränderungsereignisse verwenden. Dies wird im Anschluss noch näher erläutert.

Nach der Erstellung des Beobachters weisen Sie ihn an, ein bestimmtes Element zu beobachten. Hierbei handelt es sich in der Regel um das Element, für das Sie zuvor das Veränderungsereignis registriert haben:


mutationObserver.observe(someElement, options);

Wenn Sie keinen Verweis darauf speichern, wird die Veränderungsbeobachterinstanz von der Webplattform so lange im Arbeitsspeicher gehalten, bis sie mindestens ein Element beobachtet. Wenn Sie keinen Verweis auf den Beobachter speichern, können Sie auch noch über den Rückruf des Beobachters (das Objekt this im Bereich des Rückrufs sowie der zweite Parameter für die Rückruffunktion) darauf verweisen.

Der Optionenparameter ist ein einfaches JavaScript-Objekt mit Eigenschaften, die Sie angeben müssen, um genau zu beschreiben, welche Veränderungen beobachtet werden sollen. Die Eigenschaftsoptionen entsprechen den drei weiter oben erwähnten Veränderungskategorien:

  • childList
  • attributes
  • characterData

Die Option childList mit dem Wert true bedeutet: Änderungen an den untergeordneten Elementen dieses Elements beobachten (sowohl Entfernungs- als auch Hinzufügevorgänge). Diese Option schließt Textknoten mit ein, die als untergeordnete Elemente dieses Elements hinzugefügt oder entfernt werden.

Die Option attribute mit dem Wert true bedeutet: Änderungen an den Attributen dieses Elements beobachten (sowohl Entfernung- und Hinzufügevorgänge als auch Änderungen).

Die Option characterData mit dem Wert true bedeutet Änderungen an den Textknoten dieses Elements beobachten (Änderung des Werts von Textknoten; gilt nicht für vollständig entfernte oder neu hinzugefügte Textknoten).

Eine vierte Option – subtree – ist ebenfalls von Bedeutung. Die drei vorherigen Optionen beobachten das Zielelement (standardmäßig) nur isoliert, also ohne Berücksichtigung seiner Nachfolgerelemente (Unterstruktur). Wenn Sie das Element sowie alle zugehörigen Nachfolgerelemente überwachen möchten, legen Sie die subtree-Eigenschaft auf true fest. Da es bei Veränderungsereignissen zu Bubbling im DOM kommt, ist der Einsatz der Option subtree erforderlich, um für Parität mit Veränderungsereignissen zu sorgen, die für Vorgängerelemente registriert sind.

Die folgende Tabelle gibt Aufschluss darüber, welche Veränderungsbeobachteroptionen welchen Veränderungsereignisnamen entsprechen:

Veränderungsereignis Veränderungsbeobachteroptionen Hinweise
DOMNodeInserted { childList: true, subtree: true } Rückruf muss Knotenentfernungsdatensätze manuell ignorieren
DOMNodeRemoved { childList: true, subtree: true } Rückruf muss Knotenhinzufügungsdatensätze manuell ignorieren
DOMSubtreeModified { childList: true, subtree: true } Rückruf kann nun zwischen hinzugefügten und entfernten Knoten unterscheiden
DOMAttrModified { attributes: true, subtree: true }
DOMCharacterDataModified { characterData: true, subtree: true }

 

Hinweis  Mit Veränderungsbeobachtern lassen sich auch mehrere Optionen kombinieren, um gleichzeitig untergeordnete Listen, Attribute und Zeichendaten zu beobachten.

Des Weiteren steht eine Reihe von Optionen zum Speichern der vorherigen Werte von Attributen und Zeichendatenänderungen sowie zum Einschränken des Bereichs zur Verfügung, in dem Attribute beobachtet werden müssen:

  • Die Optionen attributeOldValue und characterDataOldValue mit dem Wert true speichern den vorherigen Wert, wenn Attribute oder Zeichendaten geändert werden.
  • Die Option attributeFilter mit einem Zeichenfolgenarray von Attributnamen beschränkt die Beobachtung auf die angegebenen Attribute. Diese Option ist nur relevant, wenn die Option attributes auf true festgelegt ist.

Mit diesen Informationen kann jeder Code, in dem zuvor eine Registrierung für ein Veränderungsereignis erfolgte, durch Code ersetzt werden, der eine Registrierung für einen Veränderungsbeobachter vornimmt:


// Watch for all changes to the body element's children
document.body.addEventListener("DOMNodeInserted", nodeAddedCallback, false);
document.body.addEventListener("DOMNodeRemoved", nodeRemovedCallback, false);


Wird zu:


// Watch for all changes to the body element's children
new MutationObserver(nodesAddedAndRemovedCallback).observe(document.body, 
  { childList: true, subtree: true });


Rückrufe für Veränderungsbeobachter

Die Rückruffunktion für Veränderungsbeobachter wird mit zwei Parametern aufgerufen:

  • Eine Liste mit Datensätzen
  • Ein Verweis auf das Veränderungsbeobachterobjekt, das den Rückruf aufruft

Gehen Sie mit Bedacht vor, wenn Sie Ihre Veränderungsereignisrückrufe für Veränderungsbeobachter wiederverwenden. Tritt eine relevante Veränderung auf, erfasst das MutationObserver-Objekt die angeforderten Änderungsinformationen in einem MutationRecord-Objekt und ruft die Rückruffunktion auf. Dies geschieht jedoch erst, wenn das gesamte Skript innerhalb des aktuellen Bereichs ausgeführt wurde. Unter Umständen treten seit dem letzten Aufruf des Rückrufs mehrere Veränderungen auf (die jeweils durch ein einzelnes MutationRecord-Objekt dargestellt werden).

Der Parameter records ist ein JavaScript-Array mit MutationRecord-Objekten. Jedes Objekt des Arrays steht für eine Veränderung, die für die beobachteten Elemente aufgetreten ist.

Ein records-Parameter hat folgende Eigenschaften:

MutationRecord-Eigenschaft Beschreibung

type

Die Art der von diesem Datensatz erfassten Veränderung. Mögliche Werte: attributes, characterData, childList.

target

Das Element, für das die Veränderung protokolliert wurde. Vergleichbar mit "event.target" oder "event.srcElement".

addedNodes, removedNodes

Ein Array von Knoten, die im Rahmen der Veränderung hinzugefügt oder entfernt wurden; nur relevant, wenn type auf childList festgelegt ist. Diese Arrays sind unter Umständen leer.

previousSibling, nextSibling

Das vorherige und nächste gleichgeordnete Element des hinzugefügten oder entfernten Knotens; nur relevant, wenn type auf childList festgelegt ist. Diese Werte sind unter Umständen null.

attributeName, attributeNamespace

Name und Namespace des Attributs, das hinzugefügt, entfernt oder geändert wurde. Der Wert ist null, wenn der Datensatztyp nicht attributes lautet.

oldValue

Der vorherige Wert des Attributs oder der Zeichendaten. Der Wert ist u. U. null, falls die Veränderungsbeobachteroptionen das Kennzeichen attributeOldValue oder characterDataOldValue nicht enthalten oder wenn type auf childList festgelegt ist.

 

 

 

Anzeigen:
© 2014 Microsoft