Czy istnieje JavaScript / jQuery dom change listener?
Zasadniczo chcę, aby skrypt został uruchomiony, gdy zmieni się zawartość DIV
. Ponieważ skrypty są osobne (content script in the Chrome extension & webpage script), potrzebuję sposobu na obserwowanie zmian w stanie DOM. Mogę ustawić sondaże, ale to wygląda niechlujnie.
5 answers
Przez długi czas zdarzenia mutacji DOM3 były najlepszym dostępnym rozwiązaniem, ale zostały wycofane ze względów wydajnościowych. obserwatorzy mutacji DOM4 zastępują przestarzałe zdarzenia mutacji DOM3. Są one obecnie zaimplementowane w nowoczesnych przeglądarkach jako MutationObserver
(lub jako prefiks dostawcy WebKitMutationObserver
w starych wersjach 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
//...
});
Ten przykład nasłuchuje zmian DOM na document
i jego całym poddrzewie, i uruchomi się na zmianach atrybutów elementu jak również zmiany strukturalne. Projekt spec ma pełną listę ważnych właściwości mutacji :
ChildList
- ustawić na
true
, jeśli mają być obserwowane mutacje u dzieci docelowych.Atrybuty
- ustawione na
true
, jeśli mają być obserwowane mutacje atrybutów celu.CharacterData
- ustawione na
true
Jeśli DANE celu mają być obserwowany.Subtree
- ustawić na {[4] } Jeśli mutacje nie tylko cel, ale także potomków cel mają być obserwowane.
AttributeOldValue
- ustawione na
true
Jeśliattributes
jest ustawione na true i wartość atrybutu target przed koniecznością zarejestrowania mutacji.CharacterDataOldValue
- ustawione na
true
JeślicharacterData
jest ustawione na true i dane target zanim mutacja musi być rejestrowane.AttributeFilter
- Ustawia listę nazw lokalnych atrybutów (bez przestrzeni nazw), jeśli nie wszystkie mutacje atrybutów muszą być obserwowane.
(Ta lista jest aktualna od kwietnia 2014; można sprawdzić specyfikację dla wszelkich zmian.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
Edit
Ta odpowiedź jest teraz przestarzała. Zobacz odpowiedź apsillers .
Ponieważ dotyczy to rozszerzenia Chrome, równie dobrze możesz użyć standardowego zdarzenia DOM - DOMSubtreeModified
. Zobacz obsługę tego zdarzenia w różnych przeglądarkach. Jest obsługiwany w Chrome od 1.0.
$("#someDiv").bind("DOMSubtreeModified", function() {
alert("tree changed");
});
Zobacz działający przykład tutaj .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-14 02:24:29
Wiele witryn używa AJAX / XHR / fetch, aby dodawać, pokazywać, modyfikować zawartość dynamicznie i okno.history API zamiast nawigacji w witrynie, więc bieżący adres URL jest zmieniany programowo. Takie witryny nazywane są SPA, skrót od Single Page Application.
Zwykłe metody js wykrywania zmian strony
-
MutationObserver (docs ) do dosłownego wykrywania zmian DOM:
-
Wydajność MutationObserver do wykrywania węzłów w całym DOM .
-
Prosty przykład:
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); }
-
Detektor zdarzeń dla stron, które sygnalizują zmianę treści poprzez wysłanie zdarzenia DOM:
-
pjax:end
ondocument
używany przez wiele stron opartych na pjax, np. GitHub,
zobacz Jak uruchomić jQuery przed i po załadowaniu pjax? -
message
onwindow
używany np. przez wyszukiwarkę Google w Przeglądarka Chrome,
zobacz rozszerzenie Chrome detect Google search refresh -
yt-navigate-finish
używane przez Youtube,
zobacz jak wykryć nawigację strony na YouTube i płynnie zmodyfikować jej wygląd?
-
-
Okresowe sprawdzanie DOM poprzez setInterval :
Oczywiście będzie to działać tylko w przypadku, gdy poczekasz na konkretny element zidentyfikowany przez jego id / Selektor, i nie pozwoli Ci to powszechnie wykrywać nowych dynamicznie dodawanych zawartość, chyba że wymyślisz jakiś rodzaj odcisku palca istniejącej zawartości. -
Cloaking Historia API:
let _pushState = History.prototype.pushState; History.prototype.pushState = function (state, title, url) { _pushState.call(this, state, title, url); console.log('URL changed', url) };
-
Listening to hashchange, popstate wydarzenia:
window.addEventListener('hashchange', e => { console.log('URL hash changed', e); doSomething(); }); window.addEventListener('popstate', e => { console.log('State changed', e); doSomething(); });
Extensions-specific methods
Wszystkie wyżej wymienione metody mogą być użyte w skrypcie content . Zauważ, że skrypty zawartości nie są automatycznie wykonywane przez przeglądarkę w przypadku programowa nawigacja przez okno.historia na stronie internetowej, ponieważ tylko adres URL został zmieniony, ale sama strona pozostała taka sama(Skrypty zawartości uruchamiane są automatycznie tylko raz w życiu strony).
Teraz spójrzmy na skrypt tła.
Detect URL changes in a background / strona Wydarzenia .
Istnieją zaawansowane API do pracy z nawigacją: webNavigation, webRequest , ale użyjemy prostych chrome.tabs.onUpdated detektor zdarzeń, który wysyła wiadomość do skryptu treści:
-
Manifest.json:
declare background / event page
declare content script
dodaj"tabs"
pozwolenie . -
Tło.js
var rxLookfor = /^https?:\/\/(www\.)?google\.(com|\w\w(\.\w\w)?)\/.*?[?#&]q=/; chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) { if (rxLookfor.test(changeInfo.url)) { chrome.tabs.sendMessage(tabId, 'url-update'); } });
-
Treść.js
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg === 'url-update') { // doSomething(); } });
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-26 15:43:55
Inne podejście w zależności od tego, jak zmieniasz div. Jeśli używasz JQuery do zmiany zawartości div za pomocą metody html (), możesz rozszerzyć tę metodę i wywołać funkcję rejestracji za każdym razem, gdy umieścisz html w div.
(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 );
Po prostu przechwytywamy wywołania html (), wywołujemy za pomocą tego funkcję rejestracji, która w kontekście odnosi się do elementu docelowego otrzymującego nową zawartość, a następnie przekazujemy wywołanie do oryginalnego jquery.funkcja html (). Pamiętaj, aby zwrócić wyniki oryginalnej metody html (), ponieważ jQuery oczekuje jej do łańcuchowania metod.
Aby uzyskać więcej informacji na temat nadpisywania i rozszerzania metod, sprawdź http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htm, czyli tam, gdzie zakryłem funkcję zamknięcia. Sprawdź również samouczek wtyczek na stronie JQuery.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-04 00:47:37
Oprócz "surowych" narzędzi dostarczanych przez MutationObserver
API, istnieją "wygodne" biblioteki do pracy z mutacjami DOM.
Rozważmy: MutationObserver reprezentuje każdą zmianę DOM pod względem poddziałów. Jeśli więc, na przykład, czekasz na wstawienie pewnego elementu, może on znajdować się głęboko wewnątrz dzieci mutations.mutation[i].addedNodes[j]
.
Inny problem polega na tym, że twój własny kod, w reakcji na mutacje, zmienia DOM - często chcesz go odfiltrować.
Dobra wygoda biblioteka, która rozwiązuje takie problemy to mutation-summary
(disclaimer: nie jestem autorem, tylko zadowolonym użytkownikiem), co pozwala określić zapytania tego, co Cię interesuje, i uzyskać dokładnie to.
Podstawowy przykład użycia z dokumentów:
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);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-10 12:00:26