jQuery: Klickfunktion Kinder ausschließen.

144

Ich habe versucht, meinen Kopf um die jQuery-Funktion ".not ()" zu wickeln, und bin auf ein Problem gestoßen. Ich möchte, dass das übergeordnete div "anklickbar" ist, aber wenn ein Benutzer auf ein untergeordnetes Element klickt, wird das Skript nicht aufgerufen.

$(this).not(children()).click(function(){
   $(".example").fadeOut("fast");
});

das HTML:

<div class="example">
   <div>
      <p>This content is not affected by clicks.</p>
   </div>
</div>
superUntitled
quelle

Antworten:

198

Stoppen Sie dazu den Klick auf das Kind mit .stopPropagation :

$(".example").click(function(){
  $(this).fadeOut("fast");
}).children().click(function(e) {
  return false;
});

Dadurch wird verhindert, dass die Klicks des Kindes über sein Niveau hinaus sprudeln, sodass das Elternteil den Klick nicht erhält.

.not() wird etwas anders verwendet, filtert es Elemente aus Ihrem Selektor heraus, zum Beispiel:

<div class="bob" id="myID"></div>
<div class="bob"></div>

$(".bob").not("#myID"); //removes the element with myID

Beim Klicken besteht Ihr Problem darin, dass der Klick auf ein Kind zum übergeordneten Element sprudelt und nicht, dass Sie dem Kind versehentlich einen Klick-Handler zugeordnet haben.

Nick Craver
quelle
danke nick, ich glaube nicht, dass ich danach gesucht habe. Es tut mir leid, dass ich in meiner Frage nicht klar war. Ich möchte, dass das gesamte div.example nur dann ausgeblendet wird, wenn auf das übergeordnete Element geklickt wird, nicht, wenn auf das untergeordnete div geklickt wird. Der Grund dafür ist, dass ich möchte, dass der Benutzer auf den Absatztext klicken kann und der Text nicht ausgeblendet wird. Wenn der Benutzer auf das äußere Div (übergeordnetes Div) klickt, wird alles ausgeblendet.
SuperUntitled
@superUntitled - Vielen Dank für die Klarstellung ... Die Antwort wurde aktualisiert, probieren Sie es aus.
Nick Craver
18
@Asaf - e.stopPropagation();anstelle von return false;für diesen Fall verwenden.
Nick Craver
2
Sie können auch verwenden }).find('.classes-to-ignore').click(function(e) {, um bestimmte untergeordnete Elemente auszuwählen
Paul Mason
5
Ich verstehe nicht, warum du ihm sagst, er soll es benutzen e.stopPropagation()und dann return falsestattdessen benutzen . return falseist gleichbedeutend mit e.preventDefault(); e.stopPropagation()unerwarteten Nebenwirkungen.
Steen Schütt
183

Ich verwende folgendes Markup und habe das gleiche Problem festgestellt:

<ul class="nav">
    <li><a href="abc.html">abc</a></li>
    <li><a href="def.html">def</a></li>
</ul>

Hier habe ich folgende Logik verwendet:

$(".nav > li").click(function(e){
    if(e.target != this) return; // only continue if the target itself has been clicked
    // this section only processes if the .nav > li itself is clicked.
    alert("you clicked .nav > li, but not it's children");
});

In Bezug auf die genaue Frage kann ich sehen, dass dies wie folgt funktioniert:

$(".example").click(function(e){
   if(e.target != this) return; // only continue if the target itself has been clicked
   $(".example").fadeOut("fast");
});

oder natürlich umgekehrt:

$(".example").click(function(e){
   if(e.target == this){ // only if the target itself has been clicked
       $(".example").fadeOut("fast");
   }
});

Hoffentlich hilft das.

MatCarey
quelle
28
Ich denke, das ist die bessere Lösung. Es stört die Kinder in keiner Weise und sollte eine bessere Leistung erzielen, da es möglicherweise nicht Tausende von Rückrufen registriert, wenn es Tausende von Kindern gibt.
LucasB
4
@ l2aelba - Sie sollten .on("click", ...)in neueren Versionen von jQuery verwenden, da .live()diese seit Version 1.7 veraltet sind. Siehe api.jquery.com/live
Chris
Ja, @Chris Ich habe am 16. November 12 um 10:12
l2aelba
Entschuldigung, wahrscheinlich musste ich nicht auf Ihre ID verweisen. Ich habe den Kommentar größtenteils für alle anderen hinzugefügt, die diese Antwort lesen.
Chris
1
Diese Antwort ist besser als die akzeptierte Antwort, da sie keine
Klickereignisse
24

Oder Sie können auch:

$('.example').on('click', function(e) { 
   if( e.target != this ) 
       return false;

   // ... //
});
dani24
quelle
Sie müssen false zurückgeben, um das Klickereignis in den untergeordneten Elementen zu vermeiden. Die Revision war falsch
dani24
6

Meine Lösung:

jQuery('.foo').on('click',function(event){
    if ( !jQuery(event.target).is('.foo *') ) {
        // code goes here
    } 
});
npl len
quelle
Ähnlich wie bei der obigen Lösung.
user460114
3

Ich persönlich würde dem untergeordneten Element einen Klick-Handler hinzufügen, der nichts anderes tut, als die Weitergabe des Klicks zu stoppen. Es würde also ungefähr so ​​aussehen:

$('.example > div').click(function (e) {
    e.stopPropagation();
});
Noahone
quelle
Was ist der Unterschied zwischen stopPropagationund der Rückgabe von Falsch, wie andere Antworten vermuten lassen?
Crashalot
Ich glaube, in diesem Fall wären sie genauso funktionsfähig, aber ich denke, die Stopp-Propagierung ist klarer für den Zweck dessen, was getan wird, und lässt eine bessere Chance, zu verstehen, warum es später getan wird. Aber es ist umstritten.
Noahone
Danke für die Klarstellung. Es scheint stopPropagationsauberer zu sein, da es nicht verhindert, dass Ereignisse auf untergeordneten Elementen auftreten, die bei auftreten können return false.
Crashalot
0

Hier ist ein Beispiel. Grünes Quadrat ist übergeordnetes Element und gelbes Quadrat ist untergeordnetes Element.

Hoffe das hilft.

var childElementClicked;

$("#parentElement").click(function(){

		$("#childElement").click(function(){
		   childElementClicked = true;
		});

		if( childElementClicked != true ) {

			// It is clicked on parent but not on child.
      // Now do some action that you want.
      alert('Clicked on parent');
			
		}else{
      alert('Clicked on child');
    }
    
    childElementClicked = false;
	
});
#parentElement{
width:200px;
height:200px;
background-color:green;
position:relative;
}

#childElement{
margin-top:50px;
margin-left:50px;
width:100px;
height:100px;
background-color:yellow;
position:absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="parentElement">
  <div id="childElement">
  </div>
</div>

Nole
quelle