Das Ereignis jQuery Button.click () wird zweimal ausgelöst

80

Ich habe folgendes Problem mit diesem Code:

<button id="delete">Remove items</button>

$("#delete").button({
     icons: {
             primary: 'ui-icon-trash'
     }
}).click(function() {
     alert("Clicked");
});

Wenn ich auf diese Schaltfläche klicke, wird die Warnung zweimal angezeigt. Es ist nicht nur mit dieser speziellen Schaltfläche, sondern mit jeder einzelnen Schaltfläche, die ich erstelle.

Was mache ich falsch?

user276289
quelle
Mögliches Duplikat von jQuery-Klickereignissen, die mehrmals
ausgelöst

Antworten:

66

Ihr aktueller Code funktioniert, Sie können ihn hier ausprobieren: http://jsfiddle.net/s4UyH/

Sie haben etwas außerhalb des Beispiels, das ein anderes auslöst .click(). Suchen Sie nach anderen Handlern, die ebenfalls ein clickEreignis für dieses Element auslösen .

Nick Craver
quelle
28
Sie haben Recht! Ich habe eine .unbind ("click") vor die .click () gesetzt. Jetzt funktioniert es richtig. Ich muss das Element suchen, das das Ereignis ein zweites Mal auslöst ... Vielen Dank!
user276289
1
Das klingt eher so, als hätten Sie dasselbe Klickereignis zweimal gebunden. jQuery stellt die Bindungen in die Warteschlange. Wenn Sie also mehrere Klickereignisse an dasselbe Element binden, werden beim Klicken alle ausgelöst. Der kleine Unterschied wäre, dass das Klickereignis zweimal ausgelöst wurde und dasselbe Klickereignis zweimal an das Element gebunden war.
MacAnthony
16
@ user276289 - Möglicherweise wird Ihr Code in seiner Gesamtheit mehr als einmal ausgeführt. Stellen Sie sicher, dass er nur einmal auf der Seite enthalten ist.
Nick Craver
3
Danke Nick Craver! Das war genau mein Problem. Ich hatte meinen Code in einem jQuery-Dialogfeld eingefügt, sodass er beim Rendern des jQuery-UI-Dialogfelds erneut ausgeführt wurde.
James
3
Das ist die richtige Antwort. Oft führt das doppelte Laden derselben JS-Datei auch zu diesem Fehler.
129

In diesem Fall können wir Folgendes tun

$('selected').unbind('click').bind('click', function (e) {
  do_something();
});

Das Ereignis wurde anfangs zweimal ausgelöst. Wenn die Seite aktualisiert wird, wird sie viermal ausgelöst. Es dauerte viele fruchtlose Stunden, bis ich es mit einer Google-Suche herausfand.

Ich muss auch sagen, dass der Code anfangs funktionierte, bis ich anfing, das JQueryUI-Akkordeon-Widget zu verwenden.

Simeon Abolarinwa
quelle
8
Diese Variante funktioniert auch:$('.element').unbind("click").on('click', function(e) { ... });
Rosdi Kasim
Genau das, wonach ich gesucht habe. Kann auch bestätigen, dass @RosdiKasims Kommentar korrekt ist - das habe ich verwendet.
Novocaine
Dies ist die Antwort, die ich gesucht und innerhalb von 5 Minuten erhalten habe. Danke
Alauddin Ahmed
39

Seltsames Verhalten, das ich auch erlebt habe. Also hat "return false" für mich den Trick gemacht.

        $( '#selector' ).on( 'click', function() {
            //code
            return false;
        });
Sergey Onishchenko
quelle
Vielen Dank! In meinem Fall konnte ich meinen Event-Handler nicht aufheben oder ausschalten, sondern einfach falsch zurückgeben!
bergie3000
6
Das hat auch bei mir funktioniert, aber ich würde gerne wissen warum.
Allen Liu
Schauen Sie sich Noors Antwort an.
Arman Petrosyan
1
Das hat bei mir funktioniert. Klicks werden nicht mehr als einmal ausgelöst. Wenn der Klick jedoch an ein Kontrollkästchen gebunden ist, wird er beim Klickereignis nicht aktiviert.
Rebecca Meritz
19

Wenn du benutzt

$( document ).ready({ })

oder

$(function() { });

Die Klickfunktion wird mehrmals so oft ausgelöst, wie sie verwendet wird.

Nywooz
quelle
1
Dieses Problem mit der Mine wurde behoben.
Kvvaradha
13

Sie können dies versuchen.

    $('#id').off().on('click', function() {
        // function body
    });
    $('.class').off().on('click', function() {
        // function body
    });
reza.cse08
quelle
8

Dies kann auch beide ausgelöst werden , indem inputund label innerhalb des Elements mit Klick Zuhörern.

Sie klicken auf das label, was ein Click - Ereignis und löst auch auf die anderen Click - Ereignis inputfür die label. Beide Ereignisse sprudeln zu Ihrem Element.

Sehen Sie sich diesen Stift eines ausgefallenen Nur-CSS-Schalters an: https://codepen.io/stepanh/pen/WaYzzO

Hinweis: Dies ist nicht jQuery-spezifisch. Der native Listener wird zweimal ausgelöst und im Stift angezeigt.

Stepan
quelle
Also, was sollte die Lösung dafür sein? Dies ist mein Szenario
Mars-o
3

Ich hatte das gleiche Problem und habe alles versucht, aber es hat nicht funktioniert. Also habe ich folgenden Trick angewendet:

function do_stuff(e)
{
    if(e){ alert(e); }
}
$("#delete").click(function() {
    do_stuff("Clicked");
});

Sie überprüfen, ob dieser Parameter nicht null ist als Code. Wenn die Funktion zum zweiten Mal ausgelöst wird, wird angezeigt, was Sie möchten.

Vlad Isoc
quelle
2
$("#id").off().on("click", function() {

});

Hat für mich gearbeitet.

$("#id").off().on("click", function() {

});
Shahid Hussain Abbasi
quelle
Hat auch für mich gearbeitet.
Larry Robertson
2

Dies kann folgende Gründe haben:

  1. Entweder haben Sie das Skript mehrmals in dieselbe HTML-Datei aufgenommen
  2. Sie haben den Ereignis-Listener bereits mit demonclick Attribut für das Element hinzugefügt
  3. Wenn Sie template inheritancelike extendsin verwenden django, haben Sie das Skript höchstwahrscheinlich in mehr als eine Datei aufgenommen, die durch includeoder kombiniert werdenextend
  4. Das Ereignis wird auf ein übergeordnetes Element übertragen.
  5. Wenn Sie mit djangoVorlage, haben Sie falsch ein platziertes blockineinander .

Sie sollten sie also entweder herausfinden und den doppelten Import entfernen. Es ist das Beste, was zu tun ist.

Eine andere Lösung besteht darin, alle clickEreignis-Listener zuerst im Skript zu entfernen, wie:

$("#myId").off().on("click", function(event) {
event.stopPropagation();
});

Sie können überspringen, event.stopPropagation();wenn Sie sicher sind, dass das Ereignis nicht sprudelt.

Mohammed Shareef C.
quelle
1

Ich habe festgestellt, dass das Binden einer element.click-Funktion in einer Funktion, die mehrmals vorkommt, diese in die Warteschlange stellt. Wenn Sie das nächste Mal darauf klicken, wird sie so oft ausgelöst, wie die Bindungsfunktion ausgeführt wurde. Newcomer Fehler wahrscheinlich auf meiner Seite, aber ich hoffe, es hilft. TL, DR: Stellen Sie sicher, dass Sie alle Klicks auf eine Setup-Funktion binden, die nur einmal auftritt.

igarciaoliver
quelle
1

Genau wie das, was Nick zu sagen versucht, löst etwas von außen das Ereignis zweimal aus. Um dies zu beheben, sollten Sie event.stopPropagation () verwenden, um zu verhindern, dass das übergeordnete Element sprudelt.

$('button').click(function(event) {
    event.stopPropagation();
});

Ich hoffe das hilft.

Riel Stephen Abrenio
quelle
Das hat bei mir nicht funktioniert. Etwas, das die meisten dazu geführt haben, dass der Klick mehr als einmal ausgelöst wurde.
Rebecca Meritz
1

In meinem Fall habe ich den Änderungsbefehl auf diese Weise verwendet

$(document).on('change', '.select-brand', function () {...my codes...});

und dann habe ich den weg geändert zu

$ ('. select-brand'). on ('change', function () {... meine Codes ...});

und es löste mein Problem.

sh6210
quelle
0

Wenn Sie nicht möchten, dass Ihre Schaltfläche eine Senden-Schaltfläche ist, codieren Sie sie als Elemente entfernen, die Ihr Problem lösen sollen. Wenn Sie den Typ für ein Schaltflächenelement nicht angeben, wird standardmäßig eine Senden-Schaltfläche verwendet, was zu dem von Ihnen identifizierten Problem führt.

user2672224
quelle
Sorry - wurde seltsam hochgeladen. Fügen Sie einfach type = "button" in Ihr Button-Tag ein und das sollte es tun.
user2672224
0

Bezogen auf Stepans Antwort.

In meinem Fall habe ich beides inputund labelin meinem .click()Hörer.

i ersetzt nur das labelzu div, es hat funktioniert!

Oliver Cape
quelle
0

Wenn Sie AngularJS verwenden:

Wenn Sie AngularJS verwenden und Ihr jQuery-Klickereignis INSIDE THE CONTROLLER ist , wird es durch das Angular-Framework selbst gestört und zweimal ausgelöst. Um dies zu lösen, entfernen Sie es aus dem Controller und gehen Sie wie folgt vor:

// Make sure you're using $(document), or else it won't fire.
$(document).on("click", "#myTemplateId #myButtonId", function () {
   console.log("#myButtonId is fired!");
   // Do something else.
});

angular.module("myModuleName")
   .controller("myController", bla bla bla)
Antonio Ooi
quelle