2012-03-07 21 views
27

Estoy tratando de hacer una manipulación condicional de los elementos que se agregan dinámicamente a algún contenedor en una página, pero me falta un evento.jQuery en la carga del elemento dinámico

Decir que tengo un contenedor:

<div id="container"></div> 

puedo unir fácilmente un controlador de eventos para la función de hacer clic para todos los elementos nuevos, usando

$('#container').on('click', '.sub-element', function() { ... }); 

Pero qué es lo que se unen a fin de obtener un gancho de "una sola vez" cuando el elemento se agrega al #container. He intentado enlazar a ready y load en vano. ¿Hay alguna manera de hacerlo, o tengo que encontrar otra solución a mi problema?

This fiddle contains my non-working example.

+1

* En todos los navegadores, el evento de carga no burbujea. En Internet Explorer 8 y versiones inferiores, los eventos de pegar y restablecer no se disparan. Dichos eventos no son compatibles con la delegación, pero se pueden usar cuando el controlador de eventos está directamente asociado al elemento que genera el evento. * (Http://api.jquery.com/on/) Ahora, en cuanto a cómo trabaje alrededor de eso ... – Corbin

+0

¿Sería un problema eliminar la funcionalidad 'cargar' que está intentando lograr todo junto, y en su lugar manipular el html después de que el elemento se haya agregado por 'encadenamiento'? $ ('# contenedor'). Append ('

No worky!
') .html ('yaay!'); – Ohgodwhy

+0

@Ohgodwhy no es que no se me ocurra una solución alternativa (y más aún para este ejemplo tonto), solo quiero saber si hay un evento que he echado de menos que puede usarse para el propósito que soy describiendo –

Respuesta

31

Puede desencadenar un evento personalizado en el elemento DOM recién agregado que puede ser captada por un controlador de eventos de jQuery:

//bind to our custom event for the `.sub-element` elements 
$('#container').on('custom-update', '.sub-element', function(){ 
    $(this).html('<b>yaay!</b>'); 
}); 

//append a new element to the container, 
//then select it, based on the knowledge that it is the last child of the container element, 
//and then trigger our custom event on the element 
$('#container').append('<div class="sub-element">No worky!</div>').children().last().trigger('custom-update'); 

He aquí una demostración: http://jsfiddle.net/ggHh7/4/

Este método le permite a hacer algo de forma global, incluso si carga el contenido dinámico a través de diferentes métodos.

actualización

No estoy seguro del soporte de los navegadores (voy a suponer IE8 y anteriores no admiten esto) pero se puede utilizar el evento DOMNodeInserted mutación para detectar cuando se añade un elemento DOM:

$('#container').on('DOMNodeInserted', '.sub-element', function(){ 
    $(this).html('<b>yaay!</b>'); 
}) 

$('#container').append('<div class="sub-element">No worky!</div>'); 

Aquí es una demostración: http://jsfiddle.net/ggHh7/7/

ACTUALIZACIÓN

Hay una nueva API para thi s como DOMNodeInserted se deprecia en este momento. No he mirado en él pero se llama MutationOvserver: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

+0

Interesante, +1, y todo ... por lo que está diciendo que no hay manera de que me notifiquen cuando un complemento de terceros agrega un elemento a algún contenedor. Si no soy el que lo agrega, estoy jodido? –

+3

Puede configurar un intervalo que compruebe nuevos elementos de DOM de vez en cuando. De lo contrario, hay eventos de mutación, 'DOMNodeInserted' es probablemente lo que quieres, pero el soporte del navegador puede no ser lo que necesitas: https://developer.mozilla.org/en/DOM_Client_Object_Cross-Reference/DOM_Events (Mira la' Mutación y mutación nombre de la sección de tipos de eventos). Ver mi ** actualización ** para un ejemplo de uso de 'DOMNodeInserted'. – Jasper

+0

Debería utilizar un método como Long Polling para supervisar el elemento en busca de cambios de longitud, si la longitud cambia, y luego tomar la diferencia de longitud. Eso le dará cualquier 'objeto' que reside allí. No es convencional, pero funcionará. – Ohgodwhy

6

Después de leer la respuesta anterior Ahora utilizo este éxito:

$('body').on({ 
    DOMNodeInserted : function(){ 
     alert('I have been added dynamically'); 
    }, 
    click : function(){ 
     alert('I was clicked'); 
    }, 
    '.dynamicElements' 
}); 

Ahora toda mi dynamicElements puede hacer cosas como están cargados, la utilización de la impresionante .on() mapa del evento.

Cuestiones relacionadas