Używam .on()
do wiązania zdarzeń div, które są tworzone po załadowaniu strony. Działa dobrze w przypadku kliknięcia, klawisza myszy ... ale muszę wiedzieć, kiedy został dodany nowy element div klasy MyClass. Szukam tego:
$('#MyContainer').on({
wascreated: function () { DoSomething($(this)); }
}, '.MyClass');
Jak mam to zrobic? Udało mi się napisać całą moją aplikację bez wtyczki i chcę, żeby tak zostało.
Dzięki.
Odpowiedzi:
Wcześniej można było podłączyć się do
domManip
metody jQuery, aby złapać wszystkie manipulacje jQuery dom i zobaczyć, które elementy zostały wstawione itp., Ale zespół jQuery zamknął to w jQuery 3.0+, ponieważ generalnie nie jest dobrym rozwiązaniem podłączanie się do metod jQuery w ten sposób, a oni ' sprawiliśmy, żedomManip
metoda wewnętrzna nie jest już dostępna poza podstawowym kodem jQuery.Zdarzenia mutacji również zostały wycofane, ponieważ wcześniej można było zrobić coś takiego
$(document).on('DOMNodeInserted', function(e) { if ( $(e.target).hasClass('MyClass') ) { //element with .MyClass was inserted. } });
Należy tego unikać, a obecnie zamiast tego należy używać Obserwatorów Mutacji, które działałyby w ten sposób
var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation) if (mutation.addedNodes && mutation.addedNodes.length > 0) { // element added to DOM var hasClass = [].some.call(mutation.addedNodes, function(el) { return el.classList.contains('MyClass') }); if (hasClass) { // element has class `MyClass` console.log('element ".MyClass" added'); } } }); }); var config = { attributes: true, childList: true, characterData: true }; observer.observe(document.body, config);
źródło
Oto moja wtyczka, która dokładnie to robi - jquery.initialize
Użycie jest takie samo, jak w przypadku
.each
funkcji, ale w przypadku.initialize
funkcji na elemencie, różnica.each
polega na tym, że inicjalizuje elementy dodane w przyszłości bez dodatkowego kodu - bez względu na to, czy dodasz go za pomocą AJAX, czy cokolwiek innego.Initialize ma dokładnie taką samą składnię jak w przypadku funkcji .each
$(".some-element").initialize( function(){ $(this).css("color", "blue"); });
Ale teraz, jeśli na stronie pojawi się nowy element pasujący do selektora niektórych elementów, zostanie on zainicjowany w trybie natychmiastowym. Sposób dodawania nowej pozycji nie jest ważny, nie musisz przejmować się żadnymi callbackami itp.
$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!
Plugin jest oparty na
MutationObserver
źródło
.initialize
funkcjicallback
tylko dla elementów, które są dynamicznie dodawane (np. Przez Ajax) i pominięcie wywołania zwrotnego dla elementów już obecnych podczas ładowania strony? Próbuję dodać parametr dooptions
, aby to osiągnąć, ale jak dotąd nie mam tego do pracy.$('.myClass').addClass('ignore-initialize'); $.initialize('.myClass:not(.ignore-initialize)', callback);
Po przejrzeniu tego i kilku innych postów próbowałem wydestylować to, co uważałem za najlepsze z każdego z nich, w coś prostego, co pozwoliło mi wykryć, kiedy wstawiana jest klasa elementów, a następnie działać na tych elementach .
function onElementInserted(containerSelector, elementSelector, callback) { var onMutationsObserved = function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes.length) { var elements = $(mutation.addedNodes).find(elementSelector); for (var i = 0, len = elements.length; i < len; i++) { callback(elements[i]); } } }); }; var target = $(containerSelector)[0]; var config = { childList: true, subtree: true }; var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; var observer = new MutationObserver(onMutationsObserved); observer.observe(target, config); } onElementInserted('body', '.myTargetElement', function(element) { console.log(element); });
Co ważne dla mnie, pozwala to na a) istnienie elementu docelowego na dowolnej głębokości w ramach „addedNodes” oraz b) możliwość obsługi elementu tylko przy jego pierwotnym wstawieniu (nie ma potrzeby przeszukiwania całego ustawienia dokumentu ani ignorowania „już przetworzonego”) flagi).
źródło
if(mutation.addedNodes.length)
, boaddedNodes
iremovedNodes
tablice są zawsze wmutation
rodzajuchildList
(sprawdzane w IE11, Chrome53, FF49). Wciąż +1, ponieważ twoja jest jedyną odpowiedzią, w którejaddedNodes
jest brana pod uwagę (callback
jest wywoływana tylko wtedy, gdy dodawany jest węzeł); nie tylko w tym wątku, ale w wielu innych. Wszyscy inni po prostu wywołującallback
for all mutations, nawet jeśli węzeł jest usuwany.3 lata później doświadczenia, tak słucham „elementu pewnej klasy dodanego do DOM” : po prostu dodajesz hook do
html()
funkcji jQuery , na przykład:function Start() { var OldHtml = window.jQuery.fn.html; window.jQuery.fn.html = function () { var EnhancedHtml = OldHtml.apply(this, arguments); if (arguments.length && EnhancedHtml.find('.MyClass').length) { var TheElementAdded = EnhancedHtml.find('.MyClass'); //there it is } return EnhancedHtml; } } $(Start);
To działa, jeśli używasz jQuery, co robię. I nie polega na zdarzeniu specyficznym dla przeglądarki
DOMNodeInserted
, które nie jest kompatybilne z różnymi przeglądarkami. Dodałem również tę samą implementację dla.prepend()
Ogólnie rzecz biorąc, działa to jak urok dla mnie i mam nadzieję, że dla ciebie też.
źródło
html
pomocnika jQuery do modyfikowania DOM, a nie tylko „używania jQuery” w ogóle. Elementy dodane za pomocą, powiedzmy,jQuery.append
nie wywołają tego zdarzenia.insertionQ('#intercom-container').every(function(/element){ element.style.display = 'none'; });
możesz użyć zdarzeń mutacji
http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mutationevents
EDYTOWAĆ
z MDN: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events
Przestarzałe Ta funkcja została usunięta z internetu. Chociaż niektóre przeglądarki nadal mogą go obsługiwać, jest w trakcie usuwania. Nie używaj go w starych lub nowych projektach. Strony lub aplikacje internetowe, które go używają, mogą się zepsuć w dowolnym momencie.
Obserwatorzy mutacji są proponowanym zamiennikiem zdarzeń mutacji w DOM4. Mają być zawarte w przeglądarkach Firefox 14 i Chrome 18.
https://developer.mozilla.org/en/docs/Web/API/MutationObserver
MutationObserver
zapewnia programistom sposób reagowania na zmiany w DOM. Został zaprojektowany jako zamiennik zdarzeń mutacji zdefiniowanych w specyfikacji DOM3 Events.Przykładowe użycie
Poniższy przykład pochodzi z http://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/ .
// select the target node var target = document.querySelector('#some-id'); // create an observer instance var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation.type); }); }); // configuration of the observer: var config = { attributes: true, childList: true, characterData: true }; // pass in the target node, as well as the observer options observer.observe(target, config); // later, you can stop observing observer.disconnect();
źródło
Dwa dodatki do odpowiedzi adeneo:
(1) możemy zmienić linię
return el.classList.contains('MyClass');
Do
if( el.classList ) { return el.classList.contains('MyClass'); } else { return false; }
Więc nie zobaczymy
"Uncaught TypeError: Cannot read property 'contains' of undefined"
błędu.(2) dodatek
subtree: true
wconfig
celu znalezienia dodano węzłów rekurencyjnie wszystkich dodawanych pierwiastków.źródło