2012-09-17 4 views
22

sprudelnden Können sagen wir eine HTML-Struktur wie dieseMastering Ereignis

<div id="container"> 
    <div id="nested"> 
     <span id="someElement"></span> 
    </div> 
</div> 

haben ... und unser Ziel ist es, ein Ereignis-Listener auf dem #containernur zu haben! So binden wir einen Listener (jQuery-Code)

$("#container").on('click', function(event) { 
    alert("container was clicked"); 
}); 

Das funktioniert natürlich, aber mein Problem bei diesem Ansatz ist, dass, da Ereignisse in der Regel Blase, wird auch, dass Zuhörer feuern, wenn wir tatsächlich auf #nested klicken oder #someElement . Meine aktuelle Lösung zu nur den Klick behandeln, wenn die #container geklickt wird, ist this mit event.target

$("#container").on('click', function(event) { 
    if(this === event.target) { 
     alert("container was clicked"); 
    } 
}); 

Meiner Frage zum Vergleich: Ist die „best practice“ in Betracht gezogen? Gibt es einen besseren Weg mit jQuery, um das gleiche Ergebnis "out of the box" zu erreichen?

Beispiel in Aktion: http://jsfiddle.net/FKX7p/

+3

IMO verwenden können, ist dies die beste Praxis. – VisioN

+0

@jSang: Tatsächlich haben die inneren Elemente auf einen Klick keine Zuhörer. Wird das als beste Praxis angesehen? jedes Element binden, nur um die Ausbreitung zu stoppen? –

+0

Ich sehe auch keinen besseren Ansatz, tatsächlich war ich dabei, das als Antwort zu posten, bis ich sah, dass Sie diesen Code bereits haben. –

Antwort

0

Alternative Lösung:

$("#container").click(function(){ 
    alert("container was clicked"); 
}).children().click(function(e) { 
    return false; 
}); 

Aber Ihre Lösung ist besser. jsfiddle.net/FKX7p/2/ (mit return false) OR jsfiddle.net/FKX7p/3/ (mit stopPropagation)

ziehe ich es, sie wieder in Ihrem Beispiel (Code leichter lesen wird):

if(this !== event.target) return; 
+1

Zusätzlich 'event.CurrentTarget! == event.Target' anstelle von' this' bei Bedarf verwenden, wegen der möglichen Kontextänderung von 'this' bei Verwendung von jQuery.proxy: http://api.jquery.com/jQuery .proxy/ – Nope

+0

Die alternative Lösung ist schlechter, da sie eine Menge Event-Handler hinzufügt. – naugtur

+0

@naugtur Ich stimme dir zu, aber vor der "On" -Funktion war diese Lösung beliebt. – webdeveloper

0

Ich bin nicht sicher, was man Arbeit schneller, aber es machen Sinn, dass der nächste Code wird besser:

$("#container").click(function (e) { 
    if (e.target.id && e.target.id !== "container") return false; 
}); 
+0

Jetzt überprüfe ich nur die Kennung, mit komplexen Selektoren kann ich keinen anderen Weg sehen, außer das Vergleichen der Objekte –

2

Eine alternative Möglichkeit, Ereignisse zu verhindern, sprudelt ist event.stopPropagation() zu verwenden;

$("#container").on('click', function(event) { 
    alert("container was clicked"); 
}) 
.children().on('click', function(event) { 
    event.stopPropagation(); 
}); 

Ich denke, der Vorteil dieses Ansatzes besteht darin, dass wenn Sie ein anderes Ereignis in das verschachtelte div anhängen möchten, müssen Sie nur

$("#nested").on('click', function(event) { 
    event.stopPropagation(); 
    // some action 
}); 

$("#container").on('click', function(event) { 
    alert("container was clicked"); 
});​