2013-06-10 29 views
8

I have a simple table:e.stopPropagation() funktioniert nicht wie erwartet?

enter image description here

Der TR hat <tr onclick='alert("row");'>

Und die Taste hat:

$("body").on('click',".b",function (e){ 
    alert('button'); 
    e.stopPropagation(); 
}); 

jedoch - Obwohl ich e.stopPropagation(); es noch alarmiert schrieb: "Zeile, Button".

Jetzt weiß ich, dass der Ereignishandler an die body angebracht ist und der Wähler gegen ihn (den Click Start auf der Schaltfläche überprüft und auf den Körper nach oben, wie $.live Gebrauch zu machen, aber gegen document ...).

Aber die Überprüfung sollte für die button klicken und nicht für den TR Klick sein.

Es scheint, dass, während ich zu klicken, um es in die "body" ausbreitet (weil ich Ereignishandler es angebracht ist) und während seiner Art und Weise, um den Körper nach oben den Klick auf den TR aktiviert.

Was geht hier vor? Wie kann ich meinen Code behalten (an Körper anhängen) und habe immer noch nur Alarm von "Knopf".

P.s.

Ich weiß, ich kann einfach tun:

$(".b").on('click',function (e){ 
    alert('button'); 
    e.stopPropagation(); 

}); 

aber ich möchte wissen, warum meine aktuellen Code funktioniert nicht (!).

+1

Give-Wie Sie, dass das Problem zu verstehen scheinen, ist, dass Sie den Event-Handler an den Körper befestigen, ist klar, es nicht das, was Sie‘ erneut fragen. –

+0

@dystyroy Ich habe den Handler an den Körper angeschlossen. Ja. aber ich sagte auch - "Stop Propagation". so IMHO sollte es nur "Zeile" warnen. und von dort - hör auf von oben zu gehen. –

+0

Delegierung Verwenden Sie die Propagierung des Ereignisses, um den Delegaten zu erreichen. Deshalb kann ein Ereignis, das nicht als Onload-Ereignis bubbles (propagieren), nicht mit Delegierung verwendet werden. –

Antwort

11

Das Problem ist, dass Sie den Ereignishandler an die body anfügen, auch wenn es an das Element .b delegiert. Dieser Ereignishandler wird nur aufgerufen, nachdem der Ereignishandler tr aufgerufen wurde. Daher ist es zu spät, die Weitergabe zu stoppen.

Wie ich nehme an, Sie mit dynamisch zugefügten Elementen umgehen wollen und können nicht einfach binden den Event-Handler zum td, kann ich dir vorschlagen:

$('body').on('click',"tr",function (e){ 
    alert('row'); 
}); 
$("body").on('click',".b",function (e){ 
    alert('button'); 
    e.stopPropagation(); 
}); 

Demonstration

+0

Danke distroy :-) –

5

... aber ich möchte wissen, warum mein aktueller (!) Code nicht funktioniert.

Von jQuery docs, auf event.stopPropagation mit Event-Delegation:

Da die .live() -Methode Ereignisse behandelt, sobald sie auf den Anfang des Dokuments ausgebreitet haben, ist es nicht möglich Ausbreitung zu stoppen von Live-Veranstaltungen. In ähnlicher Weise werden Ereignisse, die von .delegate() verarbeitet werden, an die Elemente weitergegeben, an die sie delegiert wurden. Ereignishandler gebunden an alle Elemente darunter in der DOM-Struktur wurde bereits bis zum Zeitpunkt der delegierten Ereignishandler ausgeführt werden. Diese Handler, , können daher verhindern, dass der delegierte Handler durch ausgelöst wird und event.stopPropagation() aufruft oder false zurückgibt.

live und delegate sind jetzt on so gilt dies.

+0

Dies ist die richtige Antwort. – andreszs

0

Mag sein, nur befestigen Sie das Ereignis nach unten Umgang mit der Taste wie (auch mit dem inline javascript-<tr> Tag angebracht) -

$("td").on('click',".b",function (e){ 
    alert('button2'); 
    e.stopPropagation(); 
}); 

OR - Statt in <tr> die inline Ereignis geben kann u

$(document).on('click',".b",function (e){ 
    alert('button'); 
    e.stopPropagation(); 
}); 

$(document).on('click',"tr",function (e){ 
    alert('tr'); 
    e.stopPropagation(); 
}); 
Verwandte Themen