2012-10-02 23 views
9

Tenía la impresión de que el controlador de eventos on de jQuery debía poder 'escuchar' elementos creados dinámicamente Y que supuestamente reemplazaría el comportamiento de live. Sin embargo, lo que he experimentado es que el uso de on no captura el evento de clics mientras que el uso de live está teniendo éxito.jQuery 'on' no se registra en ventana emergente modal generada dinámicamente

El aspecto complicado de mi situación es que yo no sólo estoy creando dinámicamente el contenido, pero lo estoy haciendo a través de una llamada AJAX .get(), e insertar el código HTML resultante en un referente .dialog() jQueryUI emergente.

Aquí es una versión simplificada de lo que estaba tratando de lograr (envuelto en $(document).ready(...)):

$.get("getUserDataAjax.php", queryString, function(formToDisplay) { 
    $("#dialog").dialog({ 
     autoOpen: true, 
     modal: true, 
     buttons... 
    }).html(formToDisplay); 
}); 
$(".classThatExistsInFormToDisplay").on("click", function() { 
    alert("This doesn't get called"); 
}); 

De la documentación para on me encontré con esto lo que así fue como me acercaba a escribir mi caso on:

$("p").on("click", function(){ 
    alert($(this).text()); 
}); 

Sin embargo, por alguna razón, live funcionará como espero - mientras que on me está fallando.

Esto no es una cuestión de "¿cómo puedo hacer que funcione" porque he encontrado que on tendrá éxito (clics de captura) si lo declaro dentrofunction(formToDisplay) la devolución de llamada.

Mi pregunta es: lo que está mal con on que no está encontrando mis elementos creados de forma dinámica dentro de una ventana emergente modal? Mi instancia de jQuery es jquery-1.7.2. jQueryUI es 1.8.21.

Aquí hay dos jsFiddles que se aproximan al problema. Haga clic en la palabra "Prueba" en ambas instancias para ver el comportamiento diferente. La única diferencia en el código es reemplazar on por live.

Donde es capturado por live.

Donde the click NO es capturado por on (haga clic en "Probar - haga clic en mí" para que no ocurra nada).

realizo que puede ser simplemente usando on inapropiadamente o pidiendo que haga algo que no estaba previsto, pero quiero saber qué no está funcionando (pero si tiene algo terriblemente inteligente, sentirse libre de compartir). Gracias por tu sabiduría!

actualización/Respuesta/Solución:

De acuerdo con el usuario 'indefinido', la diferencia es que on no se delega todo el camino desde la parte superior del objeto document mientras que hace live/es.

Como se menciona Claudio, hay partes de la documentación on que hacen referencia a elementos creados dinámicamente y que lo que se incluye en la parte $("") de la consulta necesita existir en tiempo de ejecución.

Aquí está mi nueva solución: Capturar haga clic en eventos on mi diálogo modal, que, aunque no tiene ningún contenido cuando el evento se crea en tiempo de ejecución, podrá encontrar mi contenido y elemento con clase especial que se genera luego.

$("#dialog").on("click", ".classThatExistsInFormToDisplay", function() { 
    ... //(success! Event captured) 
}); 

¡Muchísimas gracias!

Respuesta

9

live delega el evento de objeto de documento, pero on doesn 't, si se desea delegar el evento usando on método, se debe delegar el caso de uno de los padres estáticas del elemento o document objeto:

$(document).on("click", ".clickHandle", function() { 
    alert("Content clicked"); 
}); 
+0

¡Fascinante! Descubrí que tu sugerencia fue exitosa. ¡Qué grandioso! Adjunté el evento 'on' al diálogo modal y luego restringí los clics a la clase de la que realmente quiero prestar atención. Si bien esto será más disparadores que capturar solo en mi clase (una suposición) esto parece una gran solución.¡Gracias por tu respuesta! – veeTrain

+0

@veeTrain De nada. – undefined

+0

¡Eres un salvavidas, señor! Gracias. – Agent007

4

El problema es que el elemento al que se adjunta el evento debe existir.

usted tiene que utilizar on como este para capturar clics en p etiquetas creadas dinámicamente

$("#existingContainerId").on("click", "p", function(){ 
    alert($(this).text()); 
}); 

si no tiene contenedor existente relevante para usar, se puede usar $("body") o $(document)

Si el selector se omite o es nulo, al controlador de eventos se lo conoce como directo o vinculado directamente. El controlador se invoca cada vez que ocurre un evento en los elementos seleccionados, ya sea que ocurra directamente en el elemento o burbujas de un elemento descendiente (interno).

Cuando se proporciona un selector, el controlador de eventos se denomina delegado. El controlador no se llama cuando el evento ocurre directamente en el elemento vinculado, sino solo para los descendientes (elementos internos) que coinciden con el selector. jQuery burbujea el evento desde el objetivo del evento hasta el elemento donde está adjuntado el controlador (es decir, el elemento más interno al más externo) y ejecuta el controlador para cualquier elemento a lo largo de esa ruta que coincida con el selector.

Los controladores de eventos están vinculados solo a los elementos actualmente seleccionados; deben existir en la página en el momento en que su código realiza la llamada a .on(). Para garantizar que los elementos estén presentes y puedan seleccionarse, realice el enlace de eventos dentro de un manejador de documentos listos para los elementos que están en el marcado HTML en la página. Si se está inyectando HTML nuevo en la página, seleccione los elementos y adjunte controladores de eventos después de colocar el nuevo HTML en la página. O bien, utilizar eventos delegadas para fijar un controlador de eventos, como se describe a continuación

Tome un vistazo a la sección directa y delegada eventoshere para más detalles

+0

¡Allí está! Gracias por indicarme la parte relevante de la documentación para este asunto. – veeTrain

Cuestiones relacionadas