Hola, somos Arume

Desarrollamos páginas web, aplicaciones para móviles, capas de realidad aumentada y aplicaciones para Facebook. Nos apasiona la informática y somos unos perfeccionistas incurables; por eso en nuestros proyectos utilizamos estándares.

tel. 625 519 694

Mendaña de Neyra, 34, 3º B, 15008, A Coruña

Autenticarse

Registrarse. ¿Has olvidado tu contraseña?

Etiquetas

Saltar las etiquetas

Suscríbete a las RSS

Estás en:

  • Inicio >
  • Blog >
  • jQuery: asociar eventos a elementos HTML creados dinámicamente

jQuery: asociar eventos a elementos HTML creados dinámicamente

30 Dic 2011 por Luis

Comentarios: 50

jQuery

Para asociar eventos a elementos HTML con jQuery basta con usar bind() (o cualquiera de sus variantes) en el elemento y, cuando se cargue el código javascript, el evento quedará asociado. El problema viene dado cuando el elemento al que queremos asociar un evento no existe en el momento de cargar el javascript, sino que será creado dinámicamente en algún momento. Hasta que el elemento exista, no se le pueden asociar eventos. En este artículo veremos cómo podemos solucionar este problema con la función on() de jQuery.

Asociando eventos con bind

Para ilustrar el caso, voy a poner un ejemplo de lo que podríamos esperar que funcionase. Supongamos que tenemos este HTML:

<div id="blog-test-cont">
	<p class="blog-test">Pulsa para probar</p>
</div>

El código javascript sería este:

var bt_count = 0;
$("#blog-test-cont .blog-test").bind("click", function(){
	$(this).after("<p class=\"blog-test\">Pulsa para probar " + (++bt_count) + "</p>");
});

En este caso, como asociamos el evento a todos los elementos que tienen la clase blog-test, podríamos pensar que este evento se asociaría a todos los elementos que se crean dinámicamente con esa clase. Vamos a comprobar que sólo el elemento creado de antemano tiene este comportamiento:

Pulsa para probar

Esto se debe a que cuando se ejecuta el javascript, éste recorre el DOM y asocia el evento a todos los elementos que existen en ese momento que tengan la clase blog-test (descendientes del elemento blog-test-cont). Cuando se crean los elementos de forma dinámica, el javascript ya se ha ejecutado y, por lo tanto, los elementos creados después no tienen asociado el evento.

Asociando eventos con on

Este código sólo es válido para jQuery 1.7 o superior. Para versiones anteriores puede usarse delegate() (versión 1.4.3 o superior) o live(). En el último apartado veremos el mismo código con estas dos funciones.

Para que el código funcione como nosotros esperamos, en lugar de usar bind(), debemos usar on(), de esta forma:

var bt_count = 0;
$("#blog-test-cont").on("click", ".blog-test", function(){
	$(this).after("<p class=\"blog-test\">Pulsa para probar " + (++bt_count) + "</p>");
});

Veamos cómo funciona ahora:

Pulsa para probar

Podemos comprobar que ahora todos los elementos creados dinámicamente tienen el mismo comportamiento que el creado de antemano.

Esto se debe a que la función on() no asocia el evento a los elementos con clase blog-test, como hace bind(), sino que asocia el código al elemento blog-test-cont de forma que cuando el evento se dispara y se propaga por el DOM, ascendiendo hasta éste, comprueba si el elemento objetivo tiene clase blog-test y, en caso afirmativo, dispara el evento sobre él. De esta forma, no importa en qué momento se haya creado el elemento objetivo, ya que la comprobación se hace siempre que se ejecuta la acción.

Versiones anteriores de jQuery

El mismo código para versiones de jQuery menores que 1.7 y mayores o iguales a 1.4.3:

var bt_count = 0;
$("#blog-test-cont").delegate(".blog-test", "click", function(){
	$(this).after("<p class=\"blog-test\">Pulsa para probar " + (++bt_count) + "</p>");
});

El mismo código para versiones de jQuery menores que 1.4.3 y mayores o iguales a 1.3:

var bt_count = 0;
$("#blog-test-cont .blog-test").live("click", function(){
	$(this).after("<p class=\"blog-test\">Pulsa para probar " + (++bt_count) + "</p>");
});

Comentarios

50 comentarios. Comentar.

1. shabah el 15 Mar 2012 a las 13:48:53

muy muy buen documento

2. Javier Garcia el 12 Abr 2012 a las 19:10:08

Como saber cual elemento fue el que se cliqueo y activo el evento?

3. Luis el 12 Abr 2012 a las 19:53:01

Hola Javier.

El elemento que ha activado el evento se referencia dentro de la función que utilizas como $(this).

Si miras el código de ejemplo, lo que hace la función es añadir un nuevo párrafo justo después de aquel en el que se ha hecho click con $(this).after().

Un saludo.

4. wolfrozen el 03 May 2012 a las 00:00:39

Hola solo quería darte las gracias por tu explicación, que me fue muy útil para un proyecto que estoy realizando

5. Richard Omar el 19 Sep 2012 a las 07:08:44

Gracias!! Muy bueno!!

6. Javier Garcia el 23 Oct 2012 a las 18:22:45

Loco, muy claro muchas gracias se me olvidaba lo del DOM en los elementos dinamicos y no encontraba el script donde lo hice jejeje, GRACIAS!

7. Ch el 24 Ene 2013 a las 12:06:59

Gracias. Buena expliación.

8. ariel el 08 Mar 2013 a las 04:36:27

gracias.. me la pase renegando muchas veces por este problemita... muchas graciass!!!!!

9. DSK25 el 31 Mar 2013 a las 03:23:59

Gracias me sirvio. Sabe como puedo eliminar divs creados dinamicamente?

10. Suso el 15 Jun 2013 a las 15:56:34

fantástico post!!!. Voy a ponerlo en práctica

11. Rodolfo el 26 Jun 2013 a las 13:57:04

Espectacular documento. He leído 40.000 otros y no me han ayudado a resolver el problema como lo ha hecho este. Muchísimas gracias por esta aportación. Por cierto, la página, preciosa!

12. jlnegrito el 03 Jul 2013 a las 21:39:10

Gracias, una gran ayuda. Estaba creando <li> dinámicamente dentro de <ul> y no funcaba.

La solución: $('ul').on('click','li',function(){}

13. Anónimo el 06 Sep 2013 a las 06:15:55

Excelente!!! Gracias!

14. Cesar el 01 Oct 2013 a las 03:37:07

muy bueno, gracias

15. Luciano el 05 Oct 2013 a las 22:32:09

Muchas gracias, existe alguna forma de hacer lo mismo pero con el evento hover ?

16. Luciano el 05 Oct 2013 a las 22:49:33

Solucionado gracias:

Al parecer al on se le puede enviar una configuracion con los eventos

$('#tabla').on({

click : function() {…},

mouseenter: function() {…},

mouseleave: function() {…}

}, 'a.borrar');

17. Carlos el 12 Nov 2013 a las 05:59:04

gracias me ayudaste a resolver un problema que tenia, jaja

llevaba mas de dos días tratando de resolver este problema¡¡¡¡

18. Marco el 14 Feb 2014 a las 06:48:18

Muchisimas gracias viejo , estaba buscando una respuesta como esta.

Respecto a la pregunta que realizo javier Garcia , puedes obtener el id del elemnto que invoco el evento con la siguiente sentencia $(this).attr("id")

20. fernando el 17 May 2014 a las 17:58:55

Muchas gracias por compartir este trabajo, me soluciono el problema y fue un placer leer como se explica aqui.Gracias de nuevo

21. Ruth el 27 May 2014 a las 23:44:29

Muy claro, felicitaciones!

Una gran ayuda para los que empezamos con Jquery

23. @elkangri23 el 16 Jun 2014 a las 16:29:03

Mil gracias por el aporte, bastante rallado estaba con el tema, siendo principiante en jquery

24. MASTER el 01 Jul 2014 a las 17:16:00

Hola que tal he andado buscando como dare estilo a elementos dinamicos, ya que tengo un problemon esto se puede aplicar a Tab? bueno el codigo se ve sencillotendre que hacer prubas y comento

Saludos =)

25. rtyrtyrty el 15 Jul 2014 a las 19:37:20

gracias me sirvio para el boton q se genera automaticamente hasta q se hace la consulta. Batalle mucho para asociarle el evento de click al bton que se crea automaticamente

26. Franklin Ruiz el 03 Sep 2014 a las 23:23:51

Me has aclarado una duda que tenía desde hace años, no sabes cuantas líneas de código me has ahorrado. Gracias sinceras!

28. franco el 04 Dic 2014 a las 20:58:41

Genio! Muchas gracias! Una vez lo necesitaba y de vago no lo busque! Muy bien explicado! Gracias nuevamente!

29. Samo el 07 Ene 2015 a las 16:38:44

Gracias, me ha servido mucho, estoy en un nuevo empleo como programador y me salvo en una nueva tarea que realizo.

30. Francisco Rosales el 22 Ene 2015 a las 05:43:10

Tengo un div que muestra contenido input text (al dar click sale un calendario) traido vía AJAX:

<div id="contenido_traido_con_ajax">

<input type="text" class="claseX" value="calendario " />

</div>

Afuera de ese div, tengo otro input text con la misma clase:

<input type="text" class="claseX" value="calendario " />

En un javascript externo tengo las funciones que se activan al hacer

click en el input text con la class=claseX

El problema es, el input que no fue traido vía ajax funciona

perfectamente, en cambio el que sí fue traido con ajax no funciona.

Estuve googleando y al parecer es un problema muy común, e intenté

copiar una función que en teoría es como que "recarga" el javascript

para "que se de cuenta que hay html nuevo" según entendí, pero la

verdad no lo logro hacer andar.

¿Alguien tiene experiencia con un problema así?

Saludos!

31. Iván el 03 Feb 2015 a las 01:25:47

Muchas gracias por el aporte!!! Llevaba días loco tratando de solucionar esto...

32. Oscar David Díaz Fortaleché el 11 Feb 2015 a las 16:23:28

Gracias, estaba como loco buscando algo que me resolviera ese pequeño problema.

33. Anónimo el 05 Abr 2015 a las 14:04:32

Muy buen aporte!!! Muy bien explicado y muy aclaratorio :) Gracias!

34. Anónimo el 21 Abr 2015 a las 21:41:24

Tengo un problema, a mi el evento se me dispara tantas veces como lineas me queden para acabar de recorrer el objeto, esto trae el contenido de una tabla y al asociarle un evento on click me salta el alert tantas veces como lineas me queden por recorrer.

$.ajax({

type:"post",

url: "enviarTweet.php",

data: stringDato,

success: function(respuesta){

respuesta = $.parseJSON(respuesta);

var cont=1;

for(var i in respuesta){

$("#tweets").append("<div><p>"+respuesta[i].tw_text+"</p><input type='button' name='"+cont+"' value='EDITAR' /></div>");

$("#tweets").on("click","input",function(){alert("Has editado "+this.name);});

cont++;

}

}

});

37. Anónimo el 10 Jun 2015 a las 17:37:12

Como hago para enviar los datos a una base de datos.

Y despues como hago para que me muestre en el formulario los datos guardados tanto como inserte.

Gracias

38. yeison el 13 Jun 2015 a las 00:33:11

Gracias por el aporte.. fue de gran ayuda para mi

39. Agradecid@ el 01 Jul 2015 a las 11:43:30

¡Genial! Me ha resultado muy útil porque me estaba volviendo loc@.

Gracias por tu aporte.

40. Gumiel el 27 Jul 2015 a las 16:58:58

muy buen articulo ;)

41. Carlos Enrique el 29 Sep 2015 a las 16:23:38

Excelente pana, al principio pensé que el click se estaba haciendo en el div con el id, pero luego de ver el código un poco mas, vi que no es así sino al elemento que tiene la clase. Gracias por la documentación

saludos!!!

42. Carlos Enrique el 30 Sep 2015 a las 20:39:04

Hola compañeros también pueden usar este código:

$('body').on('click','a.pruebita',function(e){

e.preventDefault();

alert('Joder!!! esto es una prueba :D ');

});

43. carlos de la o el 15 Oct 2015 a las 23:42:54

muy bueno gracias

44. Anónimo el 08 Dic 2015 a las 23:40:16

y si el id no existe aun osea el q usas primero para crear el segundo bloque ... si no que se añade despues ..

te funcionara ?? ... saludos .. :D ... por q no me funciona :(

45. Anónimo el 03 Feb 2016 a las 05:39:09

gracias, me sirvio de mucho

46. Anónimo el 04 Feb 2016 a las 15:31:36

Loco me ayudó mucho. Gracias!

47. Anónimo el 30 Ago 2016 a las 21:38:41

holas tengo un problema, resulta que estoy generando un formulario dinamicamente como lo muestra en el comienzao pero a memdida que van saliendo tengo 2 select los cuales los lleno desde una tabla de la base de datos con una funcion y ajax pero me rellena el inicial y los que comienzan a salir no se m despliega nada si alguien m puede ayudar le agradeceria mucho. de ante mano muchas gracias

48. Anónimo el 28 Sep 2016 a las 18:06:02

Excelente

49. @canorioss el 24 Nov 2016 a las 20:51:55

Excelente hermano, sabía que renuncie existir una forma de solucionarlo. Yo estoy trabajando con una tabla y me sorprendí al ver que no funcionaban los <a class="eliminarItem">Eliminar</a> creados mediante ajax y jquery...

Al principio no entendía y no podía implementar tu método pero viendo y analizando mas a fondo y leyendo los comentarios he logrado que todo funcione muy bien y ahora brinque es muy simple..

Gracias Luis y a los que comentaron y pusieron ejemplos.

50. canorioss el 24 Nov 2016 a las 20:57:20

Ups! Escribí un poco a prisa...

correcciones:

*sabía que debía existir una forma de solucionarlo.

** todo funcione muy bien y ahora veo que es muy simple.

51. Andrés Benavides el 26 Ene 2017 a las 21:29:26

Gracias parcero, siempre había luchado con eso jejejejeje

52. Anonima el 19 Abr 2017 a las 00:32:42

Te amo!!! Gracias.

54. Javier el 03 Oct 2017 a las 21:11:55

Muchísimas gracias por esa explicación tan completa y sencilla de entender

55. juanjo. el 21 Nov 2017 a las 14:00:28

Hola respecto al envio de formulario los datos se pierden siempre que se usa php, hay que guardar los datos en una variable y volverla a sacar dentro del campo que quieras mostrarlo. un saludo

56. juanjo el 21 Nov 2017 a las 14:02:16

ejemplo: <?php ifisset($nombre)echo '$nombre' ?>

Comentar

Comentar de forma anónima

Puedes comentar poniendo cualquier nombre o apodo, exceptuando los nombres de usuarios registrados. Máximo de 50 caracteres.

Comentar como usuario registrado

Registrarse. ¿Has olvidado tu contraseña?