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?


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 .


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.


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

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.


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

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.


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.



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.


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.


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.


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.


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.


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!


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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.