Estoy usando .on()
para vincular eventos de divs que se crean después de que se carga la página. Funciona bien para hacer clic, mouseenter ... pero necesito saber cuándo se ha agregado un nuevo div de la clase MyClass. Estoy buscando esto:
$('#MyContainer').on({
wascreated: function () { DoSomething($(this)); }
}, '.MyClass');
¿Cómo hago esto? Me las arreglé para escribir toda mi aplicación sin un complemento y quiero que siga siendo así.
Gracias.
Respuestas:
Anteriormente, uno podía conectarse al
domManip
método de jQuery para capturar todas las manipulaciones de jQuery dom y ver qué elementos se insertaron, etc., pero el equipo de jQuery lo cerró en jQuery 3.0+, ya que generalmente no es una buena solución conectarse a los métodos de jQuery de esa manera, y ellos ' Lo hemos hecho para que eldomManip
método interno ya no esté disponible fuera del código jQuery principal.Los eventos de mutación también se han desaprobado, ya que antes se podía hacer algo como
$(document).on('DOMNodeInserted', function(e) { if ( $(e.target).hasClass('MyClass') ) { //element with .MyClass was inserted. } });
esto debe evitarse, y hoy en día se deben usar los observadores de mutaciones, que funcionarían así
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);
fuente
Aquí está mi complemento que hace exactamente eso: jquery.initialize
El uso es el mismo que usaría la
.each
función, pero con la.initialize
función en el elemento, la diferencia.each
es que también inicializará los elementos agregados en el futuro sin ningún código adicional, sin importar si lo agrega con AJAX o cualquier otra cosa.Initialize tiene exactamente la misma sintaxis que con cada función.
$(".some-element").initialize( function(){ $(this).css("color", "blue"); });
Pero ahora, si un nuevo elemento que coincide con el selector de algún elemento aparecerá en la página, se inicializará instantáneamente. La forma en que se agrega el nuevo elemento no es importante, no necesita preocuparse por las devoluciones de llamada, etc.
$("<div/>").addClass('some-element').appendTo("body"); //new element will have blue color!
El complemento se basa en
MutationObserver
fuente
.initialize
funcióncallback
solo para elementos que se agregan dinámicamente (por ejemplo, a través de Ajax) y omitir la devolución de llamada para elementos ya presentes cuando la página se carga inicialmente? Estoy tratando de agregar un parámetro paraoptions
lograr esto, pero hasta ahora no he logrado que esto funcione.$('.myClass').addClass('ignore-initialize'); $.initialize('.myClass:not(.ignore-initialize)', callback);
Después de revisar esta y varias otras publicaciones, traté de destilar lo que pensé que era lo mejor de cada una en algo simple que me permitiera detectar cuándo se inserta una clase de elementos y luego actuar sobre esos elementos .
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); });
Es importante para mí que esto permite a) que el elemento de destino exista a cualquier profundidad dentro de "addedNodes" yb) la capacidad de tratar con el elemento solo cuando se inserta inicialmente (no es necesario buscar en toda la configuración del documento o ignorar "ya procesado" banderas).
fuente
if(mutation.addedNodes.length)
porqueaddedNodes
y lasremovedNodes
matrices siempre están allí en elmutation
tipochildList
(marcado en IE11, Chrome53, FF49). Aún así +1, porque la suya es la única respuesta dondeaddedNodes
se considera (callback
se llama solo cuando se agrega un nodo); no solo en este hilo sino en muchos otros hilos. Todos los demás están invocandocallback
para todas las mutaciones, incluso si el nodo se está eliminando.3 años de experiencia más tarde, así es como escucho el "elemento de una determinada clase agregado al DOM" : simplemente agrega un gancho en la
html()
función jQuery , así: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);
Esto funciona si estás usando jQuery, que yo hago. Y no depende del evento específico del navegador
DOMNodeInserted
, que no es compatible con varios navegadores. También agregué la misma implementación para.prepend()
En general, esto funciona de maravilla para mí y, con suerte, también para ti.
fuente
html
ayudante de jQuery para modificar el DOM, no solo "usando jQuery" en general. Los elementos agregados usando, digamos,jQuery.append
no activarán este evento.insertionQ('#intercom-container').every(function(/element){ element.style.display = 'none'; });
podrías usar eventos de mutación
http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mutationevents
EDITAR
de MDN: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events
En desuso Esta función se ha eliminado de la Web. Aunque es posible que algunos navegadores aún lo admitan, está en proceso de descartarse. No lo utilice en proyectos nuevos o antiguos. Las páginas o aplicaciones web que lo utilizan pueden romperse en cualquier momento.
Los observadores de mutaciones son el reemplazo propuesto para los eventos de mutación en DOM4. Deben incluirse en Firefox 14 y Chrome 18.
https://developer.mozilla.org/en/docs/Web/API/MutationObserver
MutationObserver
proporciona a los desarrolladores una forma de reaccionar a los cambios en un DOM. Está diseñado para reemplazar los eventos de mutación definidos en la especificación de eventos DOM3.Uso de ejemplo
El siguiente ejemplo se tomó de 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();
fuente
Dos adiciones a la respuesta de adeneo:
(1) podemos cambiar la línea
return el.classList.contains('MyClass');
A
if( el.classList ) { return el.classList.contains('MyClass'); } else { return false; }
Entonces no veremos el
"Uncaught TypeError: Cannot read property 'contains' of undefined"
error.(2) Añadir
subtree: true
aconfig
encontrar nodos añadidos de forma recursiva en todos los elementos añadidos.fuente