Gibt es einen JavaScript / jQuery DOM-Änderungslistener?
402
Im Wesentlichen möchte ich ein Skript ausführen lassen, wenn sich der Inhalt einer DIVÄnderung ändert. Da die Skripte separat sind (Inhaltsskript in der Chrome-Erweiterung und im Webseiten-Skript), muss ich einfach Änderungen im DOM-Status beobachten. Ich könnte eine Umfrage einrichten, aber das scheint schlampig.
DOM3-Mutationsereignisse waren lange Zeit die beste verfügbare Lösung, wurden jedoch aus Leistungsgründen nicht mehr unterstützt. DOM4-Mutationsbeobachter sind der Ersatz für veraltete DOM3-Mutationsereignisse. Sie werden derzeit in modernen Browsern als MutationObserver(oder als Herstellerpräfix WebKitMutationObserverin alten Chrome-Versionen) implementiert :
MutationObserver= window.MutationObserver|| window.WebKitMutationObserver;var observer =newMutationObserver(function(mutations, observer){// fired when a mutation occurs
console.log(mutations, observer);// ...});// define what element should be observed by the observer// and what types of mutations trigger the callback
observer.observe(document,{
subtree:true,
attributes:true//...});
In diesem Beispiel werden DOM-Änderungen documentund der gesamte Teilbaum abgehört und Änderungen an Elementattributen sowie strukturelle Änderungen ausgelöst. Die Entwurfsspezifikation enthält eine vollständige Liste der gültigen Eigenschaften des Mutations-Listeners :
childList
Stellen Sie ein, trueob Mutationen an den Kindern des Ziels beobachtet werden sollen.
Attribute
Stellen Sie ein, trueob Mutationen an den Attributen des Ziels beobachtet werden sollen.
ZeichenDaten
Stellen Sie ein, trueob Mutationen an den Daten des Ziels beobachtet werden sollen.
Teilbaum
Stellen Sie ein, trueob Mutationen nicht nur zum Ziel, sondern auch zu den Nachkommen des Ziels beobachtet werden sollen.
attributeOldValue
Setzen Sie auf trueif attributesauf true und den Attributwert des Ziels, bevor die Mutation aufgezeichnet werden muss.
characterDataOldValue
Setzen Sie auf trueif characterDataauf true und die Daten des Ziels, bevor die Mutation aufgezeichnet werden muss.
attributeFilter
Auf eine Liste lokaler Attributnamen (ohne Namespace) setzen, wenn nicht alle Attributmutationen beachtet werden müssen.
(Diese Liste ist ab April 2014 aktuell. Sie können die Spezifikation auf Änderungen überprüfen.)
@AshrafBashir Ich sehe, dass das Beispiel in Firefox 19.0.2 einwandfrei funktioniert: Ich sehe, dass es ([{}])an der Konsole protokolliert ist, was den erwarteten Wert anzeigt, MutationRecordwenn ich darauf klicke . Bitte überprüfen Sie es erneut, da es sich möglicherweise um einen vorübergehenden technischen Fehler in JSFiddle handelt. Ich habe es noch nicht im IE getestet, da ich keinen IE 10 habe, der derzeit die einzige Version ist, die Mutationsereignisse unterstützt.
Apsiller
1
Ich habe gerade eine Antwort gepostet, die in IE10 + und fast allem anderen funktioniert.
Naugtur
1
Die Spezifikation scheint kein grünes Kästchen mehr zu haben, in dem die Optionen für den Mutationsbeobachter aufgeführt sind. Es listet die Optionen in Abschnitt 5.3.1 auf und beschreibt sie etwas weiter unten.
LS
2
@LS Danke, ich habe den Link aktualisiert, das Bit über dem grünen Kästchen entfernt und die gesamte Liste in meiner Antwort bearbeitet (nur für den Fall, dass der zukünftige Link verrottet).
Diese Antwort ist jetzt veraltet. Siehe die Antwort von Apsillers .
Da dies für eine Chrome-Erweiterung gilt, können Sie auch das Standard-DOM-Ereignis verwenden DOMSubtreeModified. Informationen zur Unterstützung dieses Ereignisses finden Sie in allen Browsern. Es wird in Chrome seit 1.0 unterstützt.
Funktioniert immer noch, wenn Sie Chrome-Erweiterungen erstellen. von unschätzbarem Wert.
Konzept47
49
Viele Websites verwenden AJAX, um Inhalte dynamisch hinzuzufügen / anzuzeigen / zu ändern. Manchmal wird es anstelle der In-Site-Navigation verwendet, sodass die aktuelle URL programmgesteuert geändert wird und Inhaltsskripte in diesem Fall nicht automatisch vom Browser ausgeführt werden, da die Seite nicht vollständig vom Remote-Server abgerufen wird.
Übliche JS-Methoden zum Erkennen von Seitenänderungen, die in einem Inhaltsskript verfügbar sind .
MutationObserver ( docs ), um DOM-Änderungen buchstäblich zu erkennen:
Regelmäßige Überprüfung des DOM über setInterval :
Dies funktioniert natürlich nur in Fällen, in denen Sie auf das Erscheinen eines bestimmten Elements warten, das durch seine ID / Auswahl identifiziert wird, und Sie können neue dynamisch hinzugefügte Inhalte nur dann allgemein erkennen, wenn Sie eine Art Fingerabdruck erfinden die vorhandenen Inhalte.
document.head.appendChild(document.createElement('script')).text ='('+function(){// injected DOM script is not a content script anymore, // it can modify objects and functions of the pagevar _pushState = history.pushState;
history.pushState =function(state, title, url){
_pushState.call(this, state, title, url);
window.dispatchEvent(newCustomEvent('state-changed',{detail: state}));};// repeat the above for replaceState too}+')(); this.remove();';// remove the DOM script element// And here content script listens to our DOM script custom events
window.addEventListener('state-changed',function(e){
console.log('History state changed', e.detail, location.hash);
doSomething();});
Ein anderer Ansatz hängt davon ab, wie Sie das Div ändern. Wenn Sie JQuery verwenden, um den Inhalt eines Divs mit seiner html () -Methode zu ändern, können Sie diese Methode erweitern und jedes Mal eine Registrierungsfunktion aufrufen, wenn Sie HTML in ein Div einfügen.
(function( $, oldHtmlMethod ){// Override the core html method in the jQuery object.
$.fn.html =function(){// Execute the original HTML method using the// augmented arguments collection.var results = oldHtmlMethod.apply(this, arguments );
com.invisibility.elements.findAndRegisterElements(this);return results;};})( jQuery, jQuery.fn.html );
Wir fangen nur die Aufrufe von html () ab, rufen damit eine Registrierungsfunktion auf, die sich im Kontext darauf bezieht, dass das Zielelement neuen Inhalt erhält, und leiten den Aufruf an die ursprüngliche Funktion jquery.html () weiter. Denken Sie daran, die Ergebnisse der ursprünglichen html () -Methode zurückzugeben, da JQuery dies für die Methodenverkettung erwartet.
Zusätzlich zu den von der MutationObserverAPI bereitgestellten "Raw" -Tools gibt es "Convenience" -Bibliotheken für die Arbeit mit DOM-Mutationen.
Bedenken Sie: MutationObserver repräsentiert jede DOM-Änderung in Form von Teilbäumen. Wenn Sie beispielsweise darauf warten, dass ein bestimmtes Element eingefügt wird, befindet es sich möglicherweise tief in den untergeordneten Elementen von mutations.mutation[i].addedNodes[j].
Ein weiteres Problem besteht darin, dass Ihr eigener Code als Reaktion auf Mutationen das DOM ändert - Sie möchten es häufig herausfiltern.
Eine gute Komfortbibliothek, die solche Probleme löst, ist mutation-summary(Haftungsausschluss: Ich bin nicht der Autor, nur ein zufriedener Benutzer), mit der Sie Abfragen zu Ihren Interessen angeben und genau das erhalten können.
Grundlegendes Anwendungsbeispiel aus den Dokumenten:
([{}])
an der Konsole protokolliert ist, was den erwarteten Wert anzeigt,MutationRecord
wenn ich darauf klicke . Bitte überprüfen Sie es erneut, da es sich möglicherweise um einen vorübergehenden technischen Fehler in JSFiddle handelt. Ich habe es noch nicht im IE getestet, da ich keinen IE 10 habe, der derzeit die einzige Version ist, die Mutationsereignisse unterstützt.Bearbeiten
Diese Antwort ist jetzt veraltet. Siehe die Antwort von Apsillers .
Da dies für eine Chrome-Erweiterung gilt, können Sie auch das Standard-DOM-Ereignis verwenden
DOMSubtreeModified
. Informationen zur Unterstützung dieses Ereignisses finden Sie in allen Browsern. Es wird in Chrome seit 1.0 unterstützt.Sehen Sie ein funktionierendes Beispiel hier .
quelle
Viele Websites verwenden AJAX, um Inhalte dynamisch hinzuzufügen / anzuzeigen / zu ändern. Manchmal wird es anstelle der In-Site-Navigation verwendet, sodass die aktuelle URL programmgesteuert geändert wird und Inhaltsskripte in diesem Fall nicht automatisch vom Browser ausgeführt werden, da die Seite nicht vollständig vom Remote-Server abgerufen wird.
Übliche JS-Methoden zum Erkennen von Seitenänderungen, die in einem Inhaltsskript verfügbar sind .
MutationObserver ( docs ), um DOM-Änderungen buchstäblich zu erkennen:
Ereignis-Listener für Websites, die eine Änderung des Inhalts durch Senden eines DOM-Ereignisses signalisieren:
pjax:end
auf demdocument
von vielen pjax-basierten Websites zB GitHub verwendet,sieht , wie sie vor und nach einer pjax Last jQuery laufen?
message
Informationen, diewindow
beispielsweise von der Google-Suche im Chrome-Browser verwendet werden, findenSie unter Chrome-Erweiterung, um die Aktualisierung der Google-Suche zu erkennen
spfdone
document
Informationen zur Verwendung durch Youtube findenSie unter So erkennen Sie die Seitennavigation auf Youtube und ändern HTML, bevor die Seite gerendert wird.
Regelmäßige Überprüfung des DOM über setInterval :
Dies funktioniert natürlich nur in Fällen, in denen Sie auf das Erscheinen eines bestimmten Elements warten, das durch seine ID / Auswahl identifiziert wird, und Sie können neue dynamisch hinzugefügte Inhalte nur dann allgemein erkennen, wenn Sie eine Art Fingerabdruck erfinden die vorhandenen Inhalte.
Cloaking History API in einem injizierten DOM-Skript :
Hören von Hashchange- und Popstate- Ereignissen:
Erweiterungsspezifisch: Erkennen von URL-Änderungen auf einer Hintergrund- / Ereignisseite .
Es gibt erweiterte APIs für die Navigation: webNavigation , webRequest , aber wir verwenden den einfachen Ereignis-Listener chrome.tabs.onUpdated , der eine Nachricht an das Inhaltsskript sendet :
manifest.json:
declare Hintergrund / Event - Seite
declare Inhalt Skript
add
"tabs"
Erlaubnis .background.js
content.js
quelle
Ein anderer Ansatz hängt davon ab, wie Sie das Div ändern. Wenn Sie JQuery verwenden, um den Inhalt eines Divs mit seiner html () -Methode zu ändern, können Sie diese Methode erweitern und jedes Mal eine Registrierungsfunktion aufrufen, wenn Sie HTML in ein Div einfügen.
Wir fangen nur die Aufrufe von html () ab, rufen damit eine Registrierungsfunktion auf, die sich im Kontext darauf bezieht, dass das Zielelement neuen Inhalt erhält, und leiten den Aufruf an die ursprüngliche Funktion jquery.html () weiter. Denken Sie daran, die Ergebnisse der ursprünglichen html () -Methode zurückzugeben, da JQuery dies für die Methodenverkettung erwartet.
Für weitere Informationen über Verfahren überwiegende und Erweiterung Besuche http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htm , das ist , wo Ich habe die Verschlussfunktion eingestellt. Schauen Sie sich auch das Plugins-Tutorial auf der JQuery-Website an.
quelle
Zusätzlich zu den von der
MutationObserver
API bereitgestellten "Raw" -Tools gibt es "Convenience" -Bibliotheken für die Arbeit mit DOM-Mutationen.Bedenken Sie: MutationObserver repräsentiert jede DOM-Änderung in Form von Teilbäumen. Wenn Sie beispielsweise darauf warten, dass ein bestimmtes Element eingefügt wird, befindet es sich möglicherweise tief in den untergeordneten Elementen von
mutations.mutation[i].addedNodes[j]
.Ein weiteres Problem besteht darin, dass Ihr eigener Code als Reaktion auf Mutationen das DOM ändert - Sie möchten es häufig herausfiltern.
Eine gute Komfortbibliothek, die solche Probleme löst, ist
mutation-summary
(Haftungsausschluss: Ich bin nicht der Autor, nur ein zufriedener Benutzer), mit der Sie Abfragen zu Ihren Interessen angeben und genau das erhalten können.Grundlegendes Anwendungsbeispiel aus den Dokumenten:
quelle