2016-08-04 5 views
1

Ich versuche herauszufinden, wie ich am besten auf Änderungen im DOM reagieren kann.Reagieren auf Änderungen im DOM: Mutation Observer, window.addEventListener ("onresize", Callback) oder CSS-Alternativen?

Ich habe Ähnliche Beiträge über diese Zeilen lesen, wie diese one und diese one und keiner von ihnen macht es ausdrücklich klar, wenn Mutation Beobachter zu verwenden, und wenn window.addEventListener("onresize", callback) zu verwenden. Sind Mutationsbeobachter effizienter als window.addEventListener("onresize", callback)even if the resize event is throttled?

Ich habe dies unter dem CSS3-Tag eingefügt, weil es so aussieht, als gäbe es 2012, some neat CSS tricks that triggered custom resize events, und ich frage mich, ob es seitdem Innovationen gegeben hat.

+0

Siehe https://crbug.com/612962 Chrome hat die Resize Observer API hinter einem Flag implementiert. – wOxxOm

Antwort

1

Neben der Behandlung von zwei völlig unterschiedlichen und normalerweise nicht zusammenhängenden Aufgaben unterscheidet sich ihr Timing.

MutationObserver Rückruf wird als Mikrotaskanalysierer während des laufenden Ereignis ausgeführt wird, wenn keine Änderungen auf dem Bildschirm noch gemalt. Da Javascript single-threaded ist, blockiert die Ausführung des Callbacks das weitere DOM-Parsing und die gesamte JS-Engine, daher sollten Sie es sehr schnell machen (ich befürchte, die meisten Wrapper-Bibliotheken sind wegen ihrer Vielseitigkeit nicht geeignet) und vermeiden Beobachtung der gesamten document, während eine komplexe Seite geladen wird, da der Rückruf Hunderte von Malen mit vielen hinzugefügten Knoten in jeder Mutation aufgerufen werden kann.

Ereignisse ("resize" -Ereignis eingeschlossen) werden zur internen Ereigniswarteschlange hinzugefügt und verarbeitet, wenn die aktuelle Ereigniswarteschlange vollständig verarbeitet und geändert wurde. Beispielsweise kann setTimeout(callback, 0), die eine normale Ereignisaufgabe erstellt, die Rückrufausführung während einer komplexen Seitenladung für 100-1000ms verschieben.

Verwenden Sie also MutationObserver nur, wenn Sie wirklich etwas ändern möchten, bevor es gemalt wird, damit Ihre Änderungen nahtlos in die Seite integriert werden. Und natürlich wird MutationObserver nur dann eine Änderung abfangen, wenn ein tatsächlicher HTML-Attributwert geändert oder ein Knoten hinzugefügt/entfernt/geändert wurde, nicht nur eine berechnete Breite basierend auf CSS-Regeln.

2

Diese beiden sind verschiedene Werkzeuge, um verschiedene Probleme zu lösen. Mutationsbeobachter werden verwendet, um auf die Änderungen in DOM zu reagieren. Angenommen, Sie möchten eine JavaScript-Funktion schreiben, die auf der gesamten Seite ein Wort in ein anderes Wort ersetzt, ohne dass der Endbenutzer etwas bemerkt. Sie könnten setInterval hier verwenden, aber es besteht die Gefahr, dass Inhalt beim Laden vom Server (oder asynchronem AJAX-Aufruf) "blinkt", es sei denn, Sie legen das Intervall auf einen sehr kleinen Wert fest. In diesem Fall wird es zu einer sehr ressourcenintensiven Lösung.

Also stattdessen könnten Sie eine Mutation Beobachter schreiben, die jedes Mal aufgerufen wird, wenn es eine Änderung im DOM gibt, die das Seitenrendering oder Javascript Hinzufügen/Entfernen/Ändern von HTML-Elementen auf der ganzen Linie enthält. Ein Client-seitiges A/B-Test-Tool, das ich einmal geschrieben habe, nutzte diese, um Änderungen in DOM zu erfassen und sie so schnell wie möglich zu verarbeiten.

Hinzufügen von Listener zu onresize -Ereignis tut genau das - es wird aufgerufen, wenn die Größe des Browserfensters geändert wird, unabhängig vom DOM-Status an diesem Punkt. Diese beiden sind also nicht wirklich austauschbar. Mutationsbeobachter können auf schwereren Seiten relativ "ressourcenintensiv" werden, so dass Sie dort möglicherweise eine Drosselung implementieren müssen. Was Sie brauchen, hängt von dem speziellen Fall ab, mit dem Sie es zu tun haben, keine Möglichkeit, das sicher zu beantworten.

+0

Danke für Ihre Antwort @Tadas Paplauskas.Wenn ich einen Mutation Observer habe, der das width-Attribut eines Elements beobachtet, und weil es prozentbasiert ist, weiß ich, dass es sich auch bei der Fenstergrößenanpassung ändern wird. Welches sollte ich verwenden? – user5508297

+0

Wenn Sie nur an der Größenanpassung interessiert sind und es sich anhört, dann gehen Sie auf jeden Fall mit onresize event - es ist genau für Fälle wie Ihres entworfen und sollte eine bessere Leistung bieten. –

+0

MutationObserver fängt nur dann ein, wenn sich ein tatsächlicher * html-Attribut * -Wert ändert, nicht nur eine berechnete Breite basierend auf CSS-Regeln. – wOxxOm

Verwandte Themen