entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

3votos

Evento on(); duplica el evento click(); en jQuery en elemento cargado dinamicamente

Buenas noches tengo una duda que no he podido resolver, estoy utilizando jQuer en uno de mis proyectos y estoy cargando una parte con ajax, bueno cualquier evento dentro del DOM funciona bien, el problema se presenta cuando ejecuto un evento a un elemento que fue cargado vía ajax. bueno un ejemplo.

$('element').click(function(){ /*funcion a ejecutar.*/  });

El problema:

(function($){
     $(document).ready(function(){
          $(document).on('click','elemento',function(){
                /* funcion a ejecutar*/
             });
        });
})(jQuery);

El problema es que cuando le doy click a "elemento" con el método on(); se ejecuta la acción dos veces, esto lo averigüe cuando le coloqué un contador para que se pudiera ejecutar la acción solamente una vez

 (function($){
     $(document).ready(function(){
      var inicio=0;
        $(document).on('click','elemento',function(){
          if( inicio == 0){ 
             /*funcion a ejecutar*/
             inicio++ /*cambio inicio para que solamente se ejecute una vez*/
          }
       });
    });
})(jQuery);

Bueno con esto se puede resolver el problema cuando se hace un único click el problema es que esta función devenía de funcionar para diferentes elementos con la misma clase.

Alguien me puede decir en donde está el error en mi fragmento de código o una mejor forma de utilizar en evento click() con on(), o una forma diferente de acceder a elementos que fueron creados dinámicamente.

gracias.

1voto

carlossevi comentado

Revisa este ejemplo tan simplificado que he preparado http://jsfiddle.net/fj0f7jvt/ porque ahí se vé que no se duplica el evento simplemente por añadirlo mediante on() en lugar de click(). En el ejemplo que te he puesto ambos casos tienen el mismo comportamiento.

Tendrás que compartir más partes de tu código para que veamos el motivo real de que tu función se ejecute dos veces.

1voto

josecruzchavez10 comentado

Hola carlosssevi, gracias por tu respuesta, tiempo y ejemplo, ya revisé todo mi código y no ejecuto dos veces la acción o no coloco a mis 'elementos' algún evento previo, traté sacando la función on(); de la función de llamada

$(document).ready(...);

y tampoco funcionó, bueno buscando encontré una solución que no se si sea la correcta. jQuery tiene un evento llamado "stopPropagation();" el cual sirve para hacer que se ejecute la acción una única vez y se detiene, una ves que se vuelve a ejecutar el evento on, se ejecuta una vez más y se vuelve a detener, por el momento ya puedo avanzar con mi proyecto haciendo uso de este evento de esta forma.

$(document).on('click','elemento',function(e){
e.stopPropagation();
  /*mi codigo*/
});

Por otro lado, no entiendo porqué en tu ejemplo si funciona con normalidad el evento on(); para más detalles estoy utilizando jQuery 2.1.1 llamado desde google y lo estoy colocando en el pie de mi sitio web. En tu ejemplo cambié la versión de jQuery y en vez de colocar el alert coloque una etiqueta que reciba los datos y los coloco con HTML(); y todo parece funcionar perfectamente.

También estoy haciendo la llamada de diferentes plugin despues de la llamada de jquery y hasta el final estoy llamado mi archivo .JS personalizado. de esta forma.

<body>

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/themes/smoothness/jquery-ui.css">
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/jquery.numeric.min.js"></script>
<script src="js/jquery.form.min.js"></script>
<script src="js/jquery.countdown.js"></script>
<script src="js/custom.js"></script>
 </body>
</html>

1voto

josecruzchavez10 comentado

Solucioné mi problema con un selector más fino, gracias por la ayuda de carlossevi

Editado: no es una respuesta.

1voto

carlossevi comentado

Con el comentario sobre stopPropagation() me has dado una idea ¿puede ser que el evento lo estés poniendo sobre un elemento que está anidado dentro de otro que también cumple la condición de selección de jQuery que has puesto?

Amplio el ejemplo anterior: http://jsfiddle.net/t2pg9sox/

Si se hace clic en la primera línea sólo sale un mensaje, mientras que si se hace clic en la segunda aparecen dos. La explicación es que hay un div dentro de otro, y como estoy añadiendo el evento a todos los div, cuando pincho en el segundo se ejecuta para el segundo y el primero. Me da la impresión de que con el stopPropagation() estás enmascarando un error en el selector sobre el elmento al que le quieres añadir el evento.

Podrías solucionarlo "hilando más fino" en la selección del elemento del DOM al que le quieres añadir el evento.

1voto

josecruzchavez10 comentado

Gracias una vez más por tu tiempo, en efecto tengo un elemento de la forma ".formasdepago .img-thumbnail" dentro de mi selector en mi evento on(), fui más especifico en mi selector de esta forma ".metodosajax .formasdepago .pago .img-thumbnail", como soy más especifico en el selector, por fin se ejecuta el código una sola vez sin necesidad de utilizar stopPropagation();.

Gracias. he resuelto mi problema, como puedo marcar mi pregunta como resuelta?.

2 Respuestas

3votos

carlossevi Puntos63580

Pongo mi comentario como respuesta para que quede clara la solución y puedas marcarla si quieres:

Con el comentario sobre stopPropagation() me has dado una idea
¿puede ser que el evento lo estés poniendo sobre un elemento que está
anidado dentro de otro que también cumple la condición de selección de
jQuery que has puesto?

Amplio el ejemplo anterior: http://jsfiddle.net/t2pg9sox/

Si se hace clic en la primera línea sólo sale un mensaje, mientras que
si se hace clic en la segunda aparecen dos. La explicación es que hay
un div dentro de otro, y como estoy añadiendo el evento a todos los
div, cuando pincho en el segundo se ejecuta para el segundo y el
primero. Me da la impresión de que con el stopPropagation() estás
enmascarando un error en el selector sobre el elmento al que le
quieres añadir el evento.

Podrías solucionarlo "hilando más fino" en la selección del elemento
del DOM al que le quieres añadir el evento.

Entiendo según tus comentarios posteriores que conseguiste solucionar el problema cambiando el selector.

2votos

josecruzchavez10 comentado

Si así es, mi problema estaba en el selector, gracias por tu ayuda.

2votos

Leonardo-Tadei comentado

Excelente deducción, Carlos!
Aplicar un evento a dos elementos que están anidados, produce este tipo de efectos... y es correcto que se produzcan, ya que sobre ambos elementos se dispara el evento.

2votos

Albertto Puntos180

Ese tipo de errores porque el selector se cumple un ejemplo que lo vuelve clarisimo es:

<div>
     Este es el primer div quien ejecuta el evento clic
     <div>
         Este es el segundo div que ejecuta el evento clic
     </div>
</div>

$('div').on('click', function(){
     alert();
})

Con esto pasa que el evento se ejecuta dos veces porque hay dos etiquetas que cumplen con el selector en el mismo evento.

Para evitarlo es simple. Debes de construir correctamente tu selector, recordando que si los padres de los hijos cumplen con la condición del selecto o viceversa los dos ejecutaran la función. Dicho en otras palabras: Si no vas a ejecutar funciones cuando en múltiples elementos reciban un evento. Haz selectores únicos para los elementos. También evita los eventos predeterminados que también disparan las funciones. Ejemplo de esto es:

<label for='input'>
   descripción 
   <input id='input' type='radio'>
</label>

Cuando se le da clic al botón radio, label recibe una sobre carga de eventos por lo que la funciones que tenga se ejecutaran dos veces.

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta