jQuery $ („. class”). click (); - wiele elementów, kliknij wydarzenie raz

83

Mam wiele zajęć na stronie o tej samej nazwie. Mam wtedy zdarzenie .click () w moim JS. Chcę, aby zdarzenie kliknięcia miało miejsce tylko raz, niezależnie od wielu zajęć na mojej stronie.

Scenariusz jest taki, że używam AJAX do dodawania do koszyka. Czasami na stronie głównej może znajdować się polecany produkt i najlepsza oferta, co oznacza, że ​​jest tam ta sama klasa .add. # Productid # i po kliknięciu przycisku dodaj do koszyka AJAX jest uruchamiany dwukrotnie.

Pomyślałem o utworzeniu „obszarów kliknięcia”, aby uzyskać .container-name .add. # Pid #, dając tym samym unikalne kliknięcia.

Czy to jedyne rozwiązanie?

<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});
izip
źródło
Prześlij proszę swój kod, to, co mówisz, nie ma dla mnie sensu.
Lazarus
Tak, prześlij kod swojego javascript.
Yngve B-Nilsen
1
Powinien odpalić się tylko raz, albo jest to problem z twoim HTML-em - być może jedna klasa addproduct jest zagnieżdżona w innej, albo jest błąd w module obsługi, który uruchamia ajax dwukrotnie dla jednego kliknięcia, tak czy inaczej byśmy potrzebowali, więc zobacz więcej kod dla pewności.
Simon,
3
okropne zadawanie pytań i odpowiadanie. przeżywam podobny problem, ale nigdzie w pierwszym plakacie nie wspomina się o rozwiązaniu lub metodzie szaleństwa ... tak zniechęcające, że ludzie nie mogą właściwie korzystać z tej witryny, ale oczekują, że zostaną programistami na dowolnym poziomie.
ocergynohtna
Użyj data-id = "151", a następnie $ (this) .data ('id')
Andres SK

Odpowiedzi:

121

Przepraszamy za wbijanie tego starego wątku. Miałem teraz ten sam problem i chciałem podzielić się moim rozwiązaniem.

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

event.StopPropagationi event.StopImmediatePropagation()powinien załatwić sprawę.

Posiadanie selektora .class dla modułu obsługi zdarzeń spowoduje bubblingzdarzenie click (czasami do elementu Parent, czasami do elementów Children w DOM).

event.StopPropagation()zapewnia, że ​​zdarzenie nie będzie bąbelkowe do elementów Parent, podczas gdy event.StopImmediatePropagation()metoda zapewnia, że ​​zdarzenie nie będzie bąbelkami do elementów Children żądanego selektora klasy.

Źródła: https://api.jquery.com/event.stoppropagation/ https://api.jquery.com/event.stopimmediatepropagation/

Ivan Kalafatić
źródło
1
To jest właściwe rozwiązanie. Jeśli wywołasz klasę z jQuery, może ona przejść do innych elementów i zarejestrować wiele kliknięć. Aby rozwiązać ten problem, należy zatrzymać propagację tego zdarzenia kliknięcia na inne elementy. Myślę, że niektóre inne odpowiedzi źle zrozumiały to, co najprawdopodobniej się tutaj działo.
RATKNUKKL
90
$(document).on('click', '.addproduct', function () {
    // your function here
});
Entara
źródło
Czy to działa? nigdy nie widziałem takiej funkcji
Nabeel Khan
Jak mam zadzwonić na podaną odpowiedź z innego wydarzenia?
Murad Hasan
1
Próbowałem wszystkiego, to jedyne rozwiązanie, które zadziałało.
Matt
Wyjaśnienie drugiego parametru: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

Czy możemy zobaczyć Twój moduł obsługi kliknięć? Dołączasz 5 słuchaczy do 5 różnych elementów. Jednak gdy użytkownik kliknie element, uruchamiane jest tylko jedno zdarzenie.

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

  addToCart(productId);
});

Jeśli to rozwiązanie nie zadziała, chciałbym spojrzeć na Twój moduł obsługi kliknięć.

EMMERICH
źródło
29

po kliknięciu elementu div z klasą addproduct wywoływane jest jedno zdarzenie dla tego konkretnego elementu, a nie pięć. robisz coś złego w swoim kodzie, jeśli zdarzenie zostanie uruchomione 5 razy.

Headshota
źródło
24
Uwielbiam to, jak ta odpowiedź określa oczywiste, a następnie pytający mówi, że sprawdzą swój kod, jakby to nie było coś, co zamierzali zrobić w pierwszej kolejności: D.
KI4JGT
1
Dziwię się, że to zaakceptowana odpowiedź. Jak wspomniał Ivan Kalafatić, problem polega na tym, że zdarzenie kliknięcia jest propagowane do innych elementów. Rozwiązaniem jest zatrzymanie tej propagacji. Zobacz odpowiedź Ivana Kalafaticia, jak to zrobić. edycja: właśnie zauważyłem, że poprawną odpowiedź napisał Ivan Kalafatić, a nie Machavity (który ją redagował). Naprawiłem mój błąd.
RATKNUKKL
14

W takiej sytuacji spróbuję:

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

    //your code here

 });

następnie, jeśli chcesz wykonać coś w innych elementach z tą samą klasą, kliknij jeden z nich, możesz zapętlić elementy:

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

      //your code here
     }
  );
 }
);
Paolo Anghileri
źródło
11

Myślę, że zdarzenie kliknięcia dodajesz pięć razy. Spróbuj policzyć, ile razy to robisz.

console.log('add click event')
$(".addproduct").click(function(){ });
Max7K
źródło
Korzystając z AngularJS, zauważyłem, że skopiował tag script do testowania x razy! Dzięki za możliwe rozwiązanie.
Dean Meehan
8

To powinno to naprawić i powinno być dobrym nawykiem: .unbind ()

$(".addproduct").unbind().click(function(){
   //do something 
});
SteveGSD
źródło
Zwróć uwagę, że unbind jest przestarzałe (od api.jquery.com/unbind ): od jQuery 3.0, .unbind () jest przestarzałe. Została zastąpiona przez metodę .off () od wersji 1.7 jQuery, więc jej używanie było już odradzane.
Tomer
6

Rozwiązałem to, używając wbudowanego wywołania funkcji jquery, takiego jak

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

<script>
  function testFunction(current){
     // your code go here
  }
</script>
Ravi
źródło
Ocal mój dzień, stary!
Smaïne
5

Po prostu miałem ten sam problem. W moim przypadku kod PHP generował kilka razy ten sam kod jQuery i był to wielokrotny wyzwalacz.

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

(PHP MULTIPLE GENERATER NUMBERS generowało również ten sam kod wiele razy)

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

Moim rozwiązaniem było oddzielenie skryptu w innym pliku php i załadowanie tego pliku JEDEN RAZ.

Lesenus
źródło
Twój komentarz doprowadził mnie do mojego rozwiązania - miałem ten sam problem, jedno kliknięcie wywołało zdarzenie dla każdego elementu. To dlatego, że utknąłem skrypt w częściowym widoku (asp mvc), który był ładowany wiele razy. Dziękuję Ci.
Hanshan,
2

Po prostu wprowadź kod tutaj W JQuery, jedno zdarzenie jest wyzwalane, wystarczy sprawdzić liczbę wystąpień klas w pliku i użyć pętli for dla następnej logiki. do identyfikacji liczby wystąpień dowolnej klasy, tagu lub dowolnego elementu DOM poprzez JQuery: var len = $ (". addproduct"). length;

 $(".addproduct").click(function(){
       var len = $(".addproduct").length; 
       for(var i=0;i<len;i++){
          ...
        }
 });
virendra gawale
źródło
1

Miałem ten sam problem. Powodem było to, że kilka razy miałem to samo jquery. Został umieszczony w pętli.

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

Z tego powodu strzelał wielokrotnie

Francisco Dal Cortivo
źródło
1

Sam spróbowałem tego w swoim projekcie.

Wszystkie moje wiersze w tabeli mają klasę „kontakt”:

Wszystkie moje wiersze w tabeli mają klasę „kontakt”.

Mój kod wygląda tak:

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

Po raz pierwszy przestraszyłem się zobaczyć całe moje wiersze w konsoli Firebug, kiedy wykonałem kod:

Zrzut ekranu konsoli Firebug po wykonaniu kodu

Ale potem zdałem sobie sprawę, że zdarzenie kliknięcia nie zostało uruchomione, ponieważ nie pojawiło się okno dialogowe z ostrzeżeniem. Firebug pokazuje tylko te elementy, na które ma wpływ kliknięcie. Więc nie ma się czym martwić.

Mózg
źródło
1

Spróbuj skorzystać z programu .off()obsługi:

$(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..
        }

Dołączam moduł obsługi zdarzenia kliknięcia na przycisku modalnym OK, aby działać na clickzdarzenie obiektu z klasą.archive-link .

Po pierwszym kliknięciu zdarzenie jest wywoływane tylko na tym .archive-linkobiekcie, na którym funkcja ma działać ( var linkObj). Ale kiedy kliknę to samo łącze po raz drugi i kliknę OK w oknie modalnym, zdarzenie zostanie uruchomione dla każdego obiektu, w .archive-linkktórym kliknąłem wcześniej.

Skorzystałem z powyższych rozwiązań ale niestety nie zadziałało. To było, gdy wywołałem .off () w funkcji modalnego kliknięcia przycisku OK, że propagacja zatrzymała się. Mam nadzieję, że to pomoże.

Kristianne Nerona
źródło
1

To pytanie zostało rozwiązane i również otrzymałem wiele odpowiedzi, ale chcę coś do niego dodać. Próbowałem dowiedzieć się, dlaczego mój element klikający odpala 77 razy, a nie raz.

w moim kodzie miałem each, uruchamiając odpowiedź JSON i wyświetlając ją jako elementy DIV z przyciskami. A potem zadeklarowałem zdarzenie kliknięcia wewnątrz każdego.

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

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

Jeśli napiszesz swój kod w ten sposób, przycisk class .test-button otrzyma wiele zdarzeń kliknięcia. Na przykład moje dane mają 77 wierszy, więc każda będzie działać 77 razy, co oznacza, że ​​odrzucę zdarzenie kliknięcia w klasie 77 razy. Po kliknięciu element zostanie odpalony 77 razy.

Ale jeśli napiszesz to w ten sposób:

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

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

deklarujesz element click po każdym. Oznacza to, że każdy uruchomi się 77 razy, a element kliknięcia zostanie zadeklarowany tylko raz. Jeśli więc klikniesz element, zostanie on uruchomiony tylko raz.

hatemjapo
źródło
1

Po prostu wykonaj poniższy kod, który działa absolutnie dobrze

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


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

}
Girish Ninama
źródło
0

Witam przepraszam za bump ten post, po prostu napotykam ten problem i chciałbym pokazać moją sprawę.

Mój kod wygląda tak.

<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>

Kod JavaScript

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

     'delete':(product_id)=>{
         //  Do some thig here
     }
 }
</script>
Rozwiązać
źródło
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>

Farouk ElKhabbaz
źródło
-5

Twoje zdarzenie jest wywoływane tylko raz ... więc ten kod może działać, spróbuj tego

    $(".addproduct,.addproduct,.addproduct,.addproduct,.addproduct").click(function(){//do     something fired 5 times});
SreBalaji Thirumalai
źródło