Ola, somos Arume

Desenvolvemos páxinas web, aplicacións para móbiles, capas de realidade aumentada e aplicacións para Facebook. Apaixónanos a informática e somos uns perfeccionistas incurables; por eso nos nosos proxectos utilizamos estándares.

tel. 625 519 694

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

Autenticarse

Rexistrarse. Esqueceches o teu contrasinal?

Etiquetas

Saltar as etiquetas

Subscríbete ás 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 Dec 2011 por Luis

Comentarios: 50

jQuery

Para asociar eventos a elementos HTML (ou calquera das súas variantes) no elemento e, cando se cargue o código javascript, o evento quedará asociado. O problema vén dado cando o elemento ó que queremos asociar un evento non existe no momento de cargar o javascript, senón que será creado dinámicamente nalgún momento. Ata que o elemento exista, non se lle poden asociar eventos. Neste artigo veremos como podemos solucionar este problema coa función on() de jQuery.

Asociando eventos con bind

Para ilustrar o caso, vou pór un exemplo do que poderiamos esperar que funcionase. Supoñamos que temos este HTML:

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

O 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>");
});

Neste caso, como asociamos o evento a todos os elementos que teñen a clase blog-test, poderiamos pensar que este evento se asociaría a todos os elementos que se crean dinámicamente con esa clase. Imos comprobar que só o elemento creado de antemán ten este comportamento:

Pulsa para probar

Isto débese a que cando se executa o javascript, este percorre o DOM e asocia o evento a todos os elementos que existen nese momento que teñan a clase blog-test (descendentes do elemento blog-test-cont). Cando se crean os elementos de forma dinámica, o javascript xa se executou e, polo tanto, os elementos creados despois non teñen asociado o evento.

Asociando eventos con on

Este código só é válido para jQuery 1.7 ou superior. Para versións anteriores pode usarse delegate() (versión 1.4.3 ou superior) ou live(). No último apartado veremos o mesmo código con estas dúas funcións.

Para que o código funcione como nós esperamos, en lugar de usar bind(), debemos usar on(), desta 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>");
});

Vexamos como funciona agora:

Pulsa para probar

Podemos comprobar que agora todos os elementos creados dinámicamente teñen o mesmo comportamento que o creado de antemán.

Isto débese a que a función on() non asocia o evento ós elementos con clase blog-test, como fai bind(), senón que asocia o código ó elemento blog-test-cont de forma que cuando o evento se dispara e se propaga polo DOM, ascendendo ata este, comproba se o elemento obxectivo ten clase blog-test e, en caso afirmativo, dispara o evento sobre el. Desta forma, non importa en que momento se creou o elemento obxectivo, xa que a comprobación faise sempre que se executa a acción.

Versións anteriores de jQuery

O mesmo código para versións de jQuery menores que 1.7 e maiores ou iguais 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>");
});

O mesmo código para versións de jQuery menores que 1.4.3 e maiores ou iguais 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 o 15 Mar 2012 ás 13:48:53

muy muy buen documento

2. Javier Garcia o 12 Abr 2012 ás 19:10:08

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

3. Luis o 12 Abr 2012 ás 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 o 03 Mai 2012 ás 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 o 19 Set 2012 ás 07:08:44

Gracias!! Muy bueno!!

6. Javier Garcia o 23 Out 2012 ás 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 o 24 Xan 2013 ás 12:06:59

Gracias. Buena expliación.

8. ariel o 08 Mar 2013 ás 04:36:27

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

9. DSK25 o 31 Mar 2013 ás 03:23:59

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

10. Suso o 15 Xuñ 2013 ás 15:56:34

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

11. Rodolfo o 26 Xuñ 2013 ás 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 o 03 Xul 2013 ás 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 o 06 Set 2013 ás 06:15:55

Excelente!!! Gracias!

14. Cesar o 01 Out 2013 ás 03:37:07

muy bueno, gracias

15. Luciano o 05 Out 2013 ás 22:32:09

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

16. Luciano o 05 Out 2013 ás 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 o 12 Nov 2013 ás 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 o 14 Feb 2014 ás 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 o 17 Mai 2014 ás 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 o 27 Mai 2014 ás 23:44:29

Muy claro, felicitaciones!

Una gran ayuda para los que empezamos con Jquery

23. @elkangri23 o 16 Xuñ 2014 ás 16:29:03

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

24. MASTER o 01 Xul 2014 ás 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 o 15 Xul 2014 ás 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 o 03 Set 2014 ás 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 o 04 Dec 2014 ás 20:58:41

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

29. Samo o 07 Xan 2015 ás 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 o 22 Xan 2015 ás 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 o 03 Feb 2015 ás 01:25:47

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

32. Oscar David Díaz Fortaleché o 11 Feb 2015 ás 16:23:28

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

33. Anónimo o 05 Abr 2015 ás 14:04:32

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

34. Anónimo o 21 Abr 2015 ás 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 o 10 Xuñ 2015 ás 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 o 13 Xuñ 2015 ás 00:33:11

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

39. Agradecid@ o 01 Xul 2015 ás 11:43:30

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

Gracias por tu aporte.

40. Gumiel o 27 Xul 2015 ás 16:58:58

muy buen articulo ;)

41. Carlos Enrique o 29 Set 2015 ás 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 o 30 Set 2015 ás 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 o 15 Out 2015 ás 23:42:54

muy bueno gracias

44. Anónimo o 08 Dec 2015 ás 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 o 03 Feb 2016 ás 05:39:09

gracias, me sirvio de mucho

46. Anónimo o 04 Feb 2016 ás 15:31:36

Loco me ayudó mucho. Gracias!

47. Anónimo o 30 Ago 2016 ás 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 o 28 Set 2016 ás 18:06:02

Excelente

49. @canorioss o 24 Nov 2016 ás 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 o 24 Nov 2016 ás 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 o 26 Xan 2017 ás 21:29:26

Gracias parcero, siempre había luchado con eso jejejejeje

52. Anonima o 19 Abr 2017 ás 00:32:42

Te amo!!! Gracias.

54. Javier o 03 Out 2017 ás 21:11:55

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

55. juanjo. o 21 Nov 2017 ás 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 o 21 Nov 2017 ás 14:02:16

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

Comentar

Comentar de forma anónima

Podes comentar poñendo calquera nome ou alcume, exceptuando os nomes de usuarios rexistrados. Máximo de 50 caracteres.

Comentar como usuario rexistrado

Rexistrarse. Esqueceches o teu contrasinal?