jQuery $ (“. clase”). click (); - varios elementos, haga clic en el evento una vez


82

Tengo varias clases en una página del mismo nombre. Luego tengo un evento .click () en mi JS. Lo que quiero que suceda es que el evento de clic solo ocurra una vez, independientemente de las múltiples clases en mi página.

El escenario es que estoy usando AJAX para agregar al carrito. A veces, en la página de inicio puede haber un producto destacado y una oferta superior, lo que significa que la misma clase .add. # Productid # está allí y cuando se hace clic en el botón de añadir al carrito, AJAX se activa dos veces.

Pensé en hacer 'áreas de clic' para tener .container-name .add. # Pid # y, por lo tanto, dar clics únicos.

¿Es esta la única solución?

<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>
<div class="addproduct 151">product info</div>


$(".addproduct").click(function(){//do something fired 5 times});

Por favor publique su código, lo que está diciendo no tiene sentido para mí.
Lázaro

Sí, publique el código de su javascript por favor.
Yngve B-Nilsen

1
Solo debería dispararse una vez, es un problema con su HTML; tal vez una clase de addproduct esté anidada en otra, o hay un error en el controlador que dispara el ajax dos veces por un clic, de cualquier manera necesitaríamos ver más completo código para estar seguro.
Simon

3
preguntas y respuestas horribles. Estoy experimentando un problema similar, pero en ningún lugar el cartel inicial menciona una resolución o un método para la locura ... tan desalentador que la gente no puede usar este sitio correctamente pero espera ser un desarrollador en cualquier nivel.
ocergynohtna

Use data-id = "151" y luego $ (this) .data ('id')
Andres SK

Respuestas:


120

Disculpas por chocar con este viejo hilo. Tenía el mismo problema en este momento y quería compartir mi solución.

$(".yourButtonClass").on('click', function(event){
    event.stopPropagation();
    event.stopImmediatePropagation();
    //(... rest of your JS code)
});

event.StopPropagationy event.StopImmediatePropagation()debería hacer el truco.

Tener un selector .class para el controlador de eventos dará como resultado un bubblingevento de clic (a veces al elemento principal, a veces a elementos secundarios en DOM).

event.StopPropagation()El método garantiza que el evento no se propague a los elementos principales, mientras que el event.StopImmediatePropagation()método garantiza que el evento no se propague a los elementos secundarios del selector de clase deseado.

Fuentes: https://api.jquery.com/event.stoppropagation/ https://api.jquery.com/event.stopimmediatepropagation/


1
Ésta es la solución correcta. Si llama a hacer clic en una clase con jQuery, puede pasar a otros elementos y registrar varios clics. Detener la propagación de ese evento de clic a otros elementos es la forma de resolver esto. Creo que algunas de las otras respuestas han entendido mal lo que probablemente estaba sucediendo aquí.
RATKNUKKL

90
$(document).on('click', '.addproduct', function () {
    // your function here
});

¿Funciona? Nunca vi en la función que se usaba así
Nabeel Khan

¿Cómo debo llamar a la respuesta dada desde otro evento?
Murad Hasan

1
Probé todo, esta es la única solución que funcionó.
Matt

Explicación del segundo parámetro:A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element.
zwlxt

45

¿Podríamos ver su controlador de clics? Estás adjuntando 5 oyentes a 5 elementos diferentes. Sin embargo, cuando el usuario hace clic en el elemento, solo se activa un evento.

$(".addproduct").click(function(){
  // Holds the product ID of the clicked element
  var productId = $(this).attr('class').replace('addproduct ', '');

  addToCart(productId);
});

Si esta solución no funciona, me gustaría ver su controlador de clics.


29

cuando hace clic en div con addproduct class, se activa un evento para ese elemento en particular, no cinco. estás haciendo algo mal en tu código si el evento se dispara 5 veces.


24
Me encanta cómo esta respuesta dice lo obvio y luego el consultante dice que van a verificar su código como si no fuera algo que iban a hacer en primer lugar: D.
KI4JGT

1
Me sorprende que esta sea la respuesta aceptada. Como mencionó Ivan Kalafatić, el problema es que el evento de clic se propaga a los otros elementos. La solución es detener esta propagación. Consulte la respuesta de Ivan Kalafatić para saber cómo hacerlo. editar: acabo de notar que la respuesta correcta fue escrita por Ivan Kalafatić y no por Machavity (quien la editó). Arreglado mi error.
RATKNUKKL

14

En esta situación, probaría:

$(document).on('click','.addproduct', function(){

    //your code here

 });

luego, si necesita realizar algo en los otros elementos con la misma clase al hacer clic en uno de ellos, puede recorrer los elementos:

$(document).on('click','.addproduct', function(){
   $('.addproduct').each( function(){

      //your code here
     }
  );
 }
);

11

Creo que agregas un evento de clic cinco veces. Trate de contar cuántas veces hace esto.

console.log('add click event')
$(".addproduct").click(function(){ });

Usando AngularJS, he notado que ha copiado la etiqueta del script para probar x veces Gracias por la posible solución.
Dean Meehan

8

Esto debería solucionarlo y debería ser un buen hábito: .unbind ()

$(".addproduct").unbind().click(function(){
   //do something 
});

Tenga en cuenta que la desvinculación ha quedado obsoleta (de api.jquery.com/unbind ): a partir de jQuery 3.0, .unbind () ha quedado obsoleta. Fue reemplazado por el método .off () desde jQuery 1.7, por lo que su uso ya estaba desaconsejado.
Tomer

6

Lo resolví usando una llamada de función jquery en línea como

<input type="text" name="testfield" onClick="return testFunction(this)" /> 

<script>
  function testFunction(current){
     // your code go here
  }
</script>

¡Me salvas el día, amigo!
Smaïne

5

Acabo de tener el mismo problema. En mi caso, el código PHP generó pocas veces el mismo código jQuery y ese fue el disparador múltiple.

<a href="#popraw" class="report" rel="884(PHP MULTIPLE GENERATER NUMBERS)">Popraw / Zgłoś</a>

(NÚMEROS DE GENERADOR MÚLTIPLE PHP generaron también el mismo código varias veces)

<script type="text/javascript">
$('.report').click(function(){...});
</script>

Mi solución fue separar el script en otro archivo php y cargar ese archivo UNA VEZ.


Su comentario me llevó a mi solución: tuve el mismo problema, un clic disparó un evento para cada elemento. Fue porque pegué el script en una vista parcial (asp mvc) que se cargó muchas veces. Gracias.
Hanshan

2

Simplemente ingrese el código aquí En JQuery, un evento se activa, simplemente verifique el número de ocurrencias de clases en el archivo y use el bucle for para la siguiente lógica. para identificar el número de ocurrencias de cualquier clase, etiqueta o elemento DOM a través de JQuery: var len = $ (". addproduct"). length;

 $(".addproduct").click(function(){
       var len = $(".addproduct").length; 
       for(var i=0;i<len;i++){
          ...
        }
 });

1

Yo tuve el mismo problema. La causa fue que tuve el mismo jquery varias veces. Fue colocado en un bucle.

$ (". AddProduct"). click (function () {});
$ (". AddProduct"). click (function () {});
$ (". AddProduct"). click (function () {});
$ (". AddProduct"). click (function () {});
$ (". AddProduct"). click (function () {});

Por esta razón estaba disparando varias veces


1

Lo probé yo mismo en mi proyecto.

Todas mis filas en una tabla tienen una clase "contacto":

Todas mis filas en una tabla tienen una clase "contacto".

Mi código se ve así:

var contactManager = {};

contactManager.showEditTools = function(row) {
  console.debug(row);
}

$('.contact').click(function(event){
  console.log("this should appear just once!");
  alert("I hope this will appear just once!");
  contactManager.showEditTools(event);
});

Y primero tuve miedo de ver todas mis filas como resultado en la consola de Firebug cuando ejecuté el código:

Captura de pantalla de la consola Firebug después de la ejecución del código

Pero luego me di cuenta de que el evento de clic no se disparó, porque no apareció ningún diálogo de alerta. Firebug le muestra solo los elementos que se ven afectados por la superposición de clic. Entonces no hay nada de qué preocuparse.


1

Intente hacer uso del .off()controlador:

$(function () {
    $(".archive-link").click(function (e) {
        var linkObj = $(this);
        var cb = $("#confirm-modal");
        cb.find(".modal-body").append("<p>Warning message.</p>");
        cb.modal('show'); 
        cb.find(".confirm-yes").click(function () {
            $(this).off(); //detach this event
            //ajax call yada yada..
        }

Adjunto un controlador de eventos de clic en un botón modal OK para actuar en el clickevento del objeto con clase .archive-link.

En el primer clic, el evento se dispara solo en ese .archive-linkobjeto sobre el que le pedí a la función que actuara ( var linkObj). Pero cuando hago clic en el mismo enlace por segunda vez y presiono Aceptar en el modal, el evento se activa en todos los objetos que tienen en los .archive-linkque hice clic antes.

Usé las soluciones anteriores pero desafortunadamente no funcionó. Fue cuando llamé a .off () dentro de la función de clic del botón OK modal que se detuvo la propagación. Espero que esto ayude.


1

Esta pregunta se ha resuelto y también recibió muchas respuestas, pero quiero agregarle algo. Estaba tratando de averiguar por qué mi elemento de clic disparaba 77 veces, y ni una sola vez.

en mi código, tenía cada uno, ejecutaba una respuesta json y la mostraba como divs con botones. Y luego declaré el evento de clic dentro de cada uno.

$(data).each(function(){
    button = $('<button>');
    button.addClass('test-button');
    button.appendTo("body");

    $('.test-button').click(function(){
        console.log('i was clicked');
    })
})

Si escribe su código de esta manera, la clase .test-button obtendrá múltiples eventos de clic. Por ejemplo, mis datos tienen 77 líneas, por lo que cada una se ejecutará 77 veces, lo que significa que rechazaré el evento de clic en la clase 77 veces. Al hacer clic en el elemento, se disparará 77 veces.

Pero si lo escribes así:

$(data).each(function(){
    button = $('<button>');
    button.addClass('test-button');
    button.appendTo("body");
})

    $('.test-button').click(function(){
        console.log('i was clicked');
    })

está declarando el elemento de clic después de cada uno. Eso significa que cada uno se ejecutará 77 veces y el elemento de clic se declarará solo una vez. Por lo tanto, si hace clic en el elemento, se activará solo una vez.


1

Simplemente haz el siguiente código, está funcionando absolutamente bien

$(".addproduct").on('click', function(event){
    event.stopPropagation();
    event.stopImmediatePropagation();
    getRecord();
});


function getRecord(){
   $(".addproduct").each(function () {
       console.log("test");
       });

}

0

Hola lo siento por golpear esta publicación solo enfrento este problema y me gustaría mostrar mi caso.

Mi código se ve así.

<button onClick="product.delete('1')" class="btn btn-danger">Delete</button>
<button onClick="product.delete('2')" class="btn btn-danger">Delete</button>
<button onClick="product.delete('3')" class="btn btn-danger">Delete</button>
<button onClick="product.delete('4')" class="btn btn-danger">Delete</button>

Código javascript

<script>
 var product = {
     //  Define your function
     'add':(product_id)=>{
          //  Do some thing here
     },

     'delete':(product_id)=>{
         //  Do some thig here
     }
 }
</script>

0

$(document).ready(function(){

    $(".addproduct").each(function(){
          $(this).unbind().click(function(){
               console.log('div is clicked, my content => ' + $(this).html());
           });
     });
}); 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="addproduct 151">product info 1</div>
<div class="addproduct 151">product info 2</div>
<div class="addproduct 151">product info 3</div>
<div class="addproduct 151">product info 4</div>
<div class="addproduct 151">product info 5</div>


-5

su evento se activa solo una vez ... por lo que este código puede funcionar intente esto

    $(".addproduct,.addproduct,.addproduct,.addproduct,.addproduct").click(function(){//do     something fired 5 times});
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.