Im Wesentlichen möchte ich, dass ein Skript ausgeführt wird, wenn der Inhalt von a DIV
Veränderung. Da die Skripte getrennt sind (Inhaltsskript in der Chrome-Erweiterung und Webseitenskript), brauche ich eine Möglichkeit, einfach Änderungen im DOM-Status zu beobachten. Ich könnte Polling einrichten, aber das scheint schlampig.
Gibt es einen JavaScript/jQuery-DOM-Change-Listener?
Fletcher Moore
Apsiller
DOM3-Mutationsereignisse waren lange Zeit die beste verfügbare Lösung, wurden jedoch aus Leistungsgründen verworfen. DOM4-Mutationsbeobachter sind der Ersatz für veraltete DOM3-Mutationsereignisse. Sie sind derzeit in modernen Browsern implementiert als MutationObserver
(oder als Anbieter-Präfix WebKitMutationObserver
in alten Versionen von Chrome):
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var observer = new MutationObserver(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
//...
});
Dieses Beispiel lauscht auf DOM-Änderungen document
und seinen gesamten Unterbaum, und es wird sowohl bei Änderungen an Elementattributen als auch bei strukturellen Änderungen ausgelöst. Der Entwurf der Spezifikation enthält eine vollständige Liste der gültigen Eigenschaften des Mutations-Listeners:
untergeordnete Liste
- Einstellen
true
wenn Mutationen zu Target-Kindern zu beobachten sind.Attribute
- Einstellen
true
wenn Mutationen an Zielattributen zu beobachten sind.Zeichendaten
- Einstellen
true
wenn Mutationen an Zieldaten zu beobachten sind.Teilbaum
- Einstellen
true
wenn Mutationen nicht nur zum Ziel, sondern auch zu den Nachkommen des Ziels zu beobachten sind.AttributAlterWert
- Einstellen
true
wennattributes
auf true und den Attributwert des Ziels gesetzt wird, bevor die Mutation aufgezeichnet werden muss.ZeichenDatenAlterWert
- Einstellen
true
wenncharacterData
auf wahr gesetzt ist und die Daten des Ziels, bevor die Mutation aufgezeichnet werden muss.Attributfilter
- Setzen Sie auf eine Liste lokaler Attributnamen (ohne Namensraum), wenn nicht alle Attributmutationen beachtet werden müssen.
(Diese Liste ist auf dem Stand von April 2014; Sie können die Spezifikation auf Änderungen überprüfen.)
-
@AshrafBashir Ich sehe, dass das Beispiel in Firefox 19.0.2 gut funktioniert: Ich verstehe
([{}])
an der Konsole angemeldet, die das erwartete anzeigtMutationRecord
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 den IE 10 nicht habe, der derzeit die einzige Version ist, die Mutationsereignisse unterstützt.– Apsiller
25. März 2013 um 15:20 Uhr
-
Ich habe gerade eine Antwort gepostet, die in IE10 + und meistens in allem anderen funktioniert.
– Nautur
6. März 2014 um 22:22 Uhr
-
Die Spezifikation scheint kein grünes Kästchen mehr zu haben, das die Optionen des Mutationsbeobachters auflistet. Es tut Listen Sie die Optionen auf in Abschnitt 5.3.1 und beschreibt sie etwas weiter unten.
– Herr Lance E. Sloan
8. April 2014 um 13:01 Uhr
-
@LS Danke, ich habe den Link aktualisiert, das Bit über das grüne Kästchen entfernt und die gesamte Liste in meiner Antwort bearbeitet (nur für den Fall einer zukünftigen Linkfäule).
– Apsiller
8. April 2014 um 14:27 Uhr
-
Hier ist eine Browser-Kompatibilitätstabelle von Kann ich verwenden.
– bdesham
8. Juli 2014 um 14:47 Uhr
Anurag
Bearbeiten
Diese Antwort ist jetzt veraltet. Siehe die Antwort von apsillers.
Da dies für eine Chrome-Erweiterung ist, können Sie auch das Standard-DOM-Ereignis verwenden – DOMSubtreeModified
. Siehe dazu den Support Veranstaltung über Browser hinweg. Es wird in Chrome seit 1.0 unterstützt.
$("#someDiv").bind("DOMSubtreeModified", function() {
alert("tree changed");
});
Sehen Sie sich ein funktionierendes Beispiel an Hier.
-
Ich habe festgestellt, dass dieses Ereignis auch nach bestimmten Selektoren ausgelöst werden kann. Ich recherchiere gerade.
– Peder Reis
25. Juli 2011 um 21:48 Uhr
-
w3.org/TR/DOM-Level-3-Events/#event-type-DOMSubtreeModified sagt, dass dieses Ereignis veraltet ist, was würden wir stattdessen verwenden?
– Maslow
4. Januar 2012 um 17:20 Uhr
-
@Maslow- Gibt es nicht! stackoverflow.com/questions/6659662/…
– Sam Ruby
21. März 2012 um 15:33 Uhr
-
Es gibt github.com/joelpurra/jquery-mutation-summary was es im Grunde für jquery-Benutzer löst.
– Capi Ätheriel
1. Oktober 2012 um 19:20 Uhr
-
Funktioniert immer noch, wenn Sie Chrome-Erweiterungen erstellen. unschätzbar.
– Konzept47
20. Dezember 2012 um 5:44 Uhr
wOxxOm
Viele Websites verwenden AJAX/XHR/Fetch, um Inhalte dynamisch hinzuzufügen, anzuzeigen und zu ändern, und die window.history-API anstelle der In-Site-Navigation, sodass die aktuelle URL programmgesteuert geändert wird. Solche Seiten werden SPA genannt, kurz für Single Page Application.
Übliche JS-Methoden zum Erkennen von Seitenänderungen
-
Mutationsbeobachter (Dokumente), um DOM-Änderungen buchstäblich zu erkennen.
Infos/Beispiele:
-
So ändern Sie den HTML-Inhalt, während er auf der Seite geladen wird
-
Leistung von MutationObserver zur Erkennung von Knoten im gesamten DOM.
-
Leichter Beobachter, um nur auf eine Änderung zu reagieren, wenn sich auch die URL geändert hat:
let lastUrl = location.href; new MutationObserver(() => { const url = location.href; if (url !== lastUrl) { lastUrl = url; onUrlChange(); } }).observe(document, {subtree: true, childList: true}); function onUrlChange() { console.log('URL changed!', location.href); }
-
-
Ereignis-Listener für Websites, die Inhaltsänderungen durch Senden eines DOM-Ereignisses signalisieren:
pjax:end
andocument
Wird von vielen pjax-basierten Seiten verwendet, z. B. GitHub,
siehe So führen Sie jQuery vor und nach einem Pjax-Ladevorgang aus?message
anwindow
Wird z. B. von der Google-Suche im Chrome-Browser verwendet,
siehe Chrome-Erweiterung erkennen Aktualisierung der Google-Sucheyt-navigate-finish
von Youtube verwendet,
siehe Wie kann man die Seitennavigation auf YouTube erkennen und ihr Erscheinungsbild nahtlos ändern?
-
Periodische Überprüfung von DOM über setInterval:
Offensichtlich funktioniert dies nur in Fällen, in denen Sie auf das Erscheinen eines bestimmten Elements warten, das durch seine ID / seinen Selektor identifiziert wird, und Sie können neue dynamisch hinzugefügte Inhalte nicht universell erkennen, es sei denn, Sie erfinden eine Art Fingerabdruck der vorhandenen Inhalte. -
Tarnung Verlaufs-API:
let _pushState = History.prototype.pushState; History.prototype.pushState = function (state, title, url) { _pushState.call(this, state, title, url); console.log('URL changed', url) };
-
Hören Hashwechsel, Popstate Veranstaltungen:
window.addEventListener('hashchange', e => { console.log('URL hash changed', e); doSomething(); }); window.addEventListener('popstate', e => { console.log('State changed', e); doSomething(); });
PS Alle diese Methoden können im Inhaltsskript einer WebExtension verwendet werden. Das liegt daran, dass der von uns betrachtete Fall darin besteht, dass die URL über history.pushState oder replaceState geändert wurde, sodass die Seite selbst mit derselben Inhaltsskriptumgebung unverändert blieb.
Zac Imboden
Ein weiterer Ansatz, je nachdem, wie Sie das div ändern. Wenn Sie JQuery verwenden, um den Inhalt eines div mit seiner html()-Methode zu ändern, können Sie diese Methode erweitern und jedes Mal, wenn Sie HTML in ein div einfügen, eine Registrierungsfunktion aufrufen.
(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 einfach die Aufrufe von html() ab, rufen damit eine Registrierungsfunktion auf, die im Kontext darauf verweist, dass das Zielelement neuen Inhalt erhält, dann leiten wir 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.
Weitere Informationen zum Überschreiben und Erweitern von Methoden finden Sie unter http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htm, wo ich die Schließfunktion abgeschrieben habe. Schauen Sie sich auch das Plugin-Tutorial auf der JQuery-Website an.
Zusätzlich zu den “rohen” Tools, die von bereitgestellt werden MutationObserver
APIgibt es “bequeme” Bibliotheken, um mit DOM-Mutationen zu arbeiten.
Bedenken Sie: MutationObserver repräsentiert jede DOM-Änderung in Form von Teilbäumen. Wenn Sie also beispielsweise darauf warten, dass ein bestimmtes Element eingefügt wird, kann es tief in den untergeordneten Elementen von sein mutations.mutation[i].addedNodes[j]
.
Ein weiteres Problem ist, wenn Ihr eigener Code als Reaktion auf Mutationen das DOM ändert – Sie möchten es oft herausfiltern.
Eine gute Convenience-Bibliothek, die solche Probleme löst, ist mutation-summary
(Haftungsausschluss: Ich bin nicht der Autor, nur ein zufriedener Benutzer), was es Ihnen ermöglicht, Anfragen zu spezifizieren, an denen Sie interessiert sind, und genau das zu bekommen.
Grundlegendes Verwendungsbeispiel aus der Dokumentation:
var observer = new MutationSummary({
callback: updateWidgets,
queries: [{
element: '[data-widget]'
}]
});
function updateWidgets(summaries) {
var widgetSummary = summaries[0];
widgetSummary.added.forEach(buildNewWidget);
widgetSummary.removed.forEach(cleanupExistingWidget);
}
Beantwortet das deine Frage? Erkennen Sie Änderungen im DOM
– Luzi
18. Juli 2020 um 7:37 Uhr