jQuery:クリック関数は子を除外します。


144

jQueryの ".not()"関数に頭を回そうとして、問題が発生しました。親divを「クリック可能」にしたいのですが、ユーザーが子要素をクリックしても、スクリプトは呼び出されません。

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

html:

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

回答:


198

これを行うには、.stopPropagationを使用して子のクリックを停止します。

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

これにより、子のクリックがレベルを超えて泡立つのを防ぎ、親がクリックを受け取らないようにします。

.not() 使用方法が少し異なります。たとえば、次のように、セレクタから要素をフィルタリングして除外します。

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

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

クリックの場合の問題は、子クリックが親まで泡立つことであり、誤ってクリックハンドラーを子にアタッチしたことではありません。


ありがとうニック、これが私が探していたものだとは思いません。私の質問がよくわからなかったのは残念です。子要素がクリックされたときではなく、親要素がクリックされたときにのみ、div.example全体をfadeOutにしたい。この理由は、ユーザーが段落テキストをクリックして、テキストfadeOutを持たないようにすることです。ユーザーが外側のdiv(親div)をクリックすると、すべてがフェードアウトします。
superUntitled

@superUntitled-説明をありがとうございます...これを行うために回答が更新されました。試してみてください。
Nick Craver

18
@Asaf- その場合のe.stopPropagation();代わりに使用しますreturn false;
Nick Craver

2
を使用}).find('.classes-to-ignore').click(function(e) {して特定の子要素を選択することもできます
Paul Mason

5
あなたが使用することを彼に言う私はなぜ理解していないe.stopPropagation()し、次に使用return false代わりに。return falseこれはと同等であるe.preventDefault(); e.stopPropagation()ため、予期しない副作用が生じる可能性があります。
SteenSchütt、2015

183

私は次のマークアップを使用しており、同じ問題を引き起こしていました:

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

ここでは、次のロジックを使用しました。

$(".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");
});

正確な質問については、次のように機能していることがわかります。

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

またはもちろんその逆:

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

お役に立てば幸いです。


28
これがより良い解決策だと思います。子に何の影響も与えず、数千の子が存在する場合、数千のコールバックを登録しない可能性があるため、パフォーマンスが向上するはずです。
LucasB 2012年

4
@ l2aelba- v1.7以降廃止予定となっているため.on("click", ...)、jQueryの最新バージョンで使用する必要があります.live()api.jquery.com/liveを
クリス

はい、@ Chrisは12月16日12:10に投稿しました
l2aelba

申し訳ありませんが、おそらくあなたのIDを参照する必要はありませんでした。この回答を読んでいる他の人のためにコメントを追加しました。
クリス

1
この回答は、子要素のクリックイベントを中断しないため、承認された回答よりも優れています
cameronjonesweb

24

または、以下も実行できます。

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

   // ... //
});

子要素のクリックイベントを回避するには、falseを返す必要があります。改訂は間違っていました
dani24

6

私の解決策:

jQuery('.foo').on('click',function(event){
    if ( !jQuery(event.target).is('.foo *') ) {
        // code goes here
    } 
});

上記のソリューションに似ています。
user460114 2018

3

個人的には、子要素にクリックハンドラを追加して、クリックの伝播を停止するだけでした。したがって、次のようになります。

$('.example > div').click(function (e) {
    e.stopPropagation();
});

stopPropagation他の回答が示唆するようにfalseを返すこととの違いは何ですか?
Crashalot

この場合、それらは同じように機能すると思いますが、何が行われているのかについては伝播の停止がより明確であり、後で行われている理由を理解する可能性が高くなります。しかし、それは議論の余地があります。
Noahone

説明をありがとう。でstopPropagation発生する可能性のある子要素のイベントの発生を停止しないため、よりクリーンなようreturn falseです。
Crashalot

0

例を示します。緑の四角は親であり、黄色の四角は子要素です。

これがお役に立てば幸いです。

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>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.