it-swarm.com.de

Das Jquery-Click-Ereignis wird zweimal ausgelöst, wenn Sie auf HTML-Label klicken

Ich habe einen div-Container, der html-Kontrollkästchen und sein Label enthält. Mit Jquery wollte ich ein Klickereignis auslösen, wenn jemand auf das Label in diesem Container klickt.

Ich sehe, dass das Jquery-Click-Ereignis zweimal ausgelöst wird, wenn ich auf das Etikett klicke!

Zu Testzwecken habe ich ein Klickereignis im Kontrollkästchen anstelle der Beschriftung .__ ausgelöst. Das Kontrollkästchen Ereignisereignis wird nur einmal so ausgelöst, wie es sein sollte.

Hier ist die Geige . http://jsfiddle.net/AnNvJ/2/

<tr>
    <td>
        <div id="test">
            <label>
                <input type="checkbox" id="1" />demo1</label>
            <label>
                <input type="checkbox" id="2" />demo2</label>
            <label>
                <input type="checkbox" id="3" />demo3</label>
        </div>
    </td>
    <td>&nbsp;</td>
    <td>&nbsp;</td>
</tr>

JQUERY

$(document).ready(function () {

    $('#test label').live('click', function (event) {
        alert('clicked');
    });


    $('#test checkbox').live('click', function (event) {
        alert('clicked');
    });

});
27
sravis

Die Funktion $('#test checkbox') wird nie aufgerufen, da Sie kein Tag mit dem Namen checkbox haben.

Und je nachdem, ob Sie die Checkbox oder das Label anklicken, wird der Callback für $('#test label') ein- oder zweimal aufgerufen ursache für das Sprudeln Da das Eingabeelement Teil der Bezeichnung ist und eine union ist und daher auch das Ereignis empfangen wurde, wenn die Bezeichnung Klick ist (es sprudelt nicht, können Sie event.stopPropagation() nicht ausführen).

Sie können dies überprüfen, wenn Sie Ihren Code auf diese Weise ändern:

 $('#test label').live('click', function (event) {
        event.stopPropagation(); //<-- has no effect to the described behavior
        console.log(event.target.tagName);
 });

Klicken Sie auf das Etikett:

LABEL
EINGANG

Klicken Sie auf die Eingabe:

EINGANG

EDIT Wenn Sie nur den Klick auf die Variable label und nicht die Checkbox handhaben möchten - und Sie können Ihre HTML-Struktur nicht ändern - können Sie einfach das Ereignis des Elements inputignorieren .

So oder so:

$('#test label').live('click', function (event) {
    if( event.target.tagName === "LABEL" ) {
         alert('clicked');
    }
});

Oder mit jQuery zum Testen:

$('#test label').live('click', function (event) {
    if( $(event.target).is("label") ) {
         alert('clicked');
    }
});
38
t.niese

Dies liegt daran, dass Sie die Eingabe in das Etikett einfügen, sodass Sie beim Klicken auf das Kontrollkästchen auch alle Eltern anklicken (das heißt Sprudeln). BEARBEITEN, @ t.niese gutschreiben: In der Tat gibt es hier kein Sprudeln, da das Problem beim Klicken auf das Etikett besteht und es nur Blasen gibt.

Um ein Doppelklick-Ereignis zu verhindern, und aktivieren Sie auch das Kontrollkästchen, das Sie verwenden können:

$(document).ready(function () {

    $('#test label').on('click', function (event) {
        event.preventDefault();
        var $check = $(':checkbox', this);
        $check.prop('checked', !$check.prop('checked'));
        alert('clicked label');
    });


    $('#test :checkbox').on('click', function (event) {
        event.stopPropagation();
        alert('clicked checkbox');
    });
});

GEIGE

Bevorzugen Sie auch die Verwendung von $.on und beachten Sie die Verwendung von :checkbox selector oder [type="checkbox"], die laut JQuery-API schneller und kompatibler sind ( Attributselektoren ).

event.preventDefault() stoppt jede Aktion, die vom Browser für das native Tag ausgeführt wird event.stopPropagation() verhindert, dass Bubbling und alle übergeordneten Handler über das Ereignis benachrichtigt werden

9
TecHunter

Das OP hat eine Lösung gefunden, um zu verhindern, dass der Click-Ereignishandler für das Label zweimal für einen einzigen Klick ausgeführt wird. Die gewählte Antwort hat auch eine gute Lösung, gibt jedoch fälschlicherweise an, dass dies nichts mit Ereignisblubbern zu tun hat.

Der Grund, warum es zwei Klicks gibt, hat mit dem Ereignisblubbern zu tun.

Durch Klicken auf ein Etikett, das einer Eingabe zugeordnet ist, werden zwei Klickereignisse ausgelöst. Das erste Klickereignis wird für das Label ausgelöst. Die Standardbehandlung dieses Klickereignisses bewirkt, dass ein zweites Klickereignis für die zugehörige Eingabe ausgelöst wird. Wenn die Eingabe von der Beschriftung abhängt, sprudelt das zweite Klickereignis zur Beschriftung. Aus diesem Grund wird der Click-Event-Handler für das Label zweimal aufgerufen.


Daher besteht eine Möglichkeit, dieses Problem zu lösen (wie das OP festgestellt hat), die Eingabe nicht innerhalb des Kennsatzelements zu platzieren. Es gibt immer noch zwei Klickereignisse, aber das zweite Klickereignis sprudelt nicht von der Eingabe zum Etikett.

Wenn sich die Eingabe nicht innerhalb der Beschriftung befindet, kann das "for" -Attribut der Beschriftung verwendet werden, um die Beschriftung der Eingabe zuzuordnen. Das "for" -Attribut muss auf den "id" -Wert der Eingabe gesetzt werden.

<input type="checkbox" id="1" />
<label for="1">demo1</label>

Eine andere Lösung wäre, das Ereignis an der Eingabe zu hindern:

$('#test :checkbox').on('click', function(event) {
    event.stopPropagation();
});

$('#test label').on('click', function() {
    alert('clicked');
});

Dann gibt es die Lösung, die in der ausgewählten Antwort enthalten ist. Das heißt, dass der Click-Handler des Labels das Ereignis ignoriert, wenn es aus der Eingabe sprudelt. Ich schreibe es jedoch lieber so:

$('#test label').on('click', function(event) {
    if (event.target == this) {
        alert('clicked');
    }
});
3
John S

Sie MÜSSEN in Ihrem Label MINDESTDefault und in Ihrem Kontrollkästchen stopPropagation verwenden:

http://jsfiddle.net/uUZyn/5/

Der Code:

$(document).ready(function () {

    $('#test label').on('click', function (event) {
      event.preventDefault();        
      alert('clicked label');
      var ele = $(this).find('input');
    if(ele.is(':checked')){
      ele.prop('checked', false);        
    }else{
      ele.prop('checked', true);
    }
  });

  $('#test :checkbox').on('click', function (event) {
    event.stopPropagation();
    alert('clicked checkbox');
  });
});

Auf diese Weise vermeiden Sie das Verhalten von @t.niese

Vielen Dank an die vorherigen Antworten, ohne sie würde ich es nicht verstehen: D.

Aktualisieren

Wie t.niese darauf hinweist, hier ist die Antwort, die ich mit dem Verhalten aktualisiert habe:

http://jsfiddle.net/uUZyn/6/

Das Prüfverhalten wurde erst nach der Verwendung von PrevDefault XD hinzugefügt

1
Chococroc

Ich bin gerade auf das gleiche Problem gestoßen, bei dem das Klicken auf das Label zwei separate Klickereignisse auslöste. Ich konnte das Problem für mich lösen, indem ich der Eingabe ein name-Attribut und ein for-Attribut der Beschriftung hinzufügte.

Zum Beispiel:

<div id="test">
    <label for="checkbox1">
        <input type="checkbox" name="checkbox1" id="1" />demo1</label>
    <label for="checkbox2">
        <input type="checkbox" name="checkbox2" id="2" />demo2</label>
    <label for="checkbox3">
        <input type="checkbox" name="checkbox3" id="3" />demo3</label>
 </div>

Kein JavaScript benötigt.

0
Will Hitchcock

Dies geschieht meistens, wenn Sie für ein X-Element mit einem untergeordneten Element Y 'Klick' auslösen und der Benutzer auf Y klickt.

Das Ereignis, auf das das Element geklickt hat, ist ein unerwünschtes Ereignis, das Sie nicht möchten.

Sie haben zwei Möglichkeiten, um dieses doppelte Auslösen zu vermeiden.

1) Verwende $ ('selector'). TriggerHandler ('any_standard_event_name') - Hiermit meine ich 'Standard', 'click', 'change', 'hover' usw. (Ich habe diese Option noch nie probiert)

2) Verwenden Sie einen benutzerdefinierten Ereignisnamen. z.B. $ ('Selector'). trigger ('my.click');

Lesen Sie mehr auf http://api.jquery.com/trigger/

0
EGL 2-101

In Bezug auf meinen Fall und die Tatsache, dass ich den MD-Button von Material Design verwende, funktionierten die oben genannten Vorschläge nicht sehr gut, da dadurch der Footprint des Bereichs, der Finger auf meinem Android empfängt, drastisch reduziert wurde. Anstelle von nur 2 TagNames zu erwähnen, würde ich manchmal von 3 (BUTTON, SPAN oder MD-ICON) aufsteigen. Auch der Vorschlag an anderer Stelle im Internet, meine Version von Aria zu ändern, hat nicht geholfen. Am Ende fand ich das Problem, dass ich jquery vor angle.js lade, obwohl die Hilfedokumentation von ng-infinate-scroll sagt, dass sie zuerst jquery laden soll. Wenn ich versuchte, Jquery nach dem Winkel-Ng-Infinate-Scroll zu laden, würde die Arbeit abgebrochen. Also habe ich die neueste Version von ng-infinate-scroll (nicht stabil) Version 1.2.0 heruntergeladen und jetzt kann ich meine jquery nach angle.js laden und mein unendlicher Scroll funktioniert mit allen Problemen, die ich mit ng-click mehrfach hatte Weg.

0
Helzgate

Meine Elemente hüllten sich auch ein. 

Also habe ich einen einfachen CSS-Trick für diese Lösung verwendet:

.off{
   pointer-events:none;
}
0
ivahidmontazer