web-dev-qa-db-ja.com

クリックイベントを子供ではなく親DIVのみに発生させるにはどうすればよいですか?

クラス分けされたfoobarを持つDIVと、そのDIVの中に含まれているクラスなしのDIVがいくつかありますが、それらはfoobarクラスを継承しているとします。

$('.foobar').on('click', function() { /*...do stuff...*/ });

私は、DIVのどこかをクリックしたときだけ、その子DIVをクリックしていないときにだけそれを起動したいと思います。

173
CaptSaltyJack

e.targetthisと同じ要素である場合は、子孫をクリックしていません。

$('.foobar').on('click', function(e) {
  if (e.target !== this)
    return;
  
  alert( 'clicked the foobar' );
});
.foobar {
  padding: 20px; background: yellow;
}
span {
  background: blue; color: white; padding: 8px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='foobar'> .foobar (alert) 
  <span>child (no alert)</span>
</div>
389
user1106925

新しいブラウザだけをターゲットにしたくない場合は、もう1つの方法があります。 CSSを追加するだけです

pointer-events: none;

あなたはクリックをキャプチャしたいdivの任意の子供たちに。これがサポート表です

http://caniuse.com/#feat=pointer-events

42
hobberwickey

あなたはあなたの好意でバブリングを使うことができます:

$('.foobar').on('click', function(e) {
    // do your thing.
}).on('click', 'div', function(e) {
    // clicked on descendant div
    e.stopPropagation();
});
24
ori
//bind `click` event handler to the `.foobar` element(s) to do work,
//then find the children of all the `.foobar` element(s)
//and bind a `click` event handler to them that stops the propagation of the event
$('.foobar').on('click', function () { ... }).children().on('click', function (event) {
    event.stopPropagation();
    //you can also use `return false;` which is the same as `event.preventDefault()` and `event.stopPropagation()` all in one (in a jQuery event handler)
});

これにより、.foobar要素のいずれかの子要素でのclickイベントの伝播(バブリング)が停止するため、イベントは.foobar要素に到達してイベントハンドラを起動することはありません。

これがデモです。 http://jsfiddle.net/bQQJP/

19
Jasper

私は受け入れられた答えを得ることができませんでした、しかしこれはトリックをするようです、少なくともVanilla JSでは。

if(e.target !== e.currentTarget) return;
6
Jens Törnell
$(".advanced ul li").live('click',function(e){
    if(e.target != this) return;
    //code
    // this code will execute only when you click to li and not to a child
})
2
Michalis

私は同じ問題を抱えていて、この解決策を思いついた(他の答えに基づいて)

 $( ".newsletter_background" ).click(function(e) {
    if (e.target == this) {
        $(".newsletter_background").hide();
    } 
});

基本的には、ターゲットがdivの場合はコードを実行し、それ以外の場合は何もしません(非表示にしないでください)。

1
Wonx2150

私のケースは似ていますが、これはあなたがfoobarをほとんど持っておらず、あなたがワンクリックごとに一つだけ閉じたい場合です。

親ケースを探す

$(".foobar-close-button-class").on("click", function () {
    $(this).parents('.foobar').fadeOut( 100 );
    // 'this' - means that you finding some parent class from '.foobar-close-button-class'
    // '.parents' -means that you finding parent class with name '.foobar'
});

子ケースを探す

$(".foobar-close-button-class").on("click", function () {
    $(this).child('.foobar-close-button-child-class').fadeOut( 100 );
    // 'this' - means that you finding some child class from '.foobar-close-button-class'
    // '.child' -means that you finding child class with name '.foobar-close-button-child-class'
});
1
Wukadin

pointer-events: none;を使用できず、最新のブラウザをターゲットにしている場合、composedPathを使用してオブジェクトの直接クリックを検出できます。

element.addEventListener("click", function (ev) {
    if (ev.composedPath()[0] === this) {
        // your code here ...
    }
})

ComposePathの詳細については、こちらをご覧ください: https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath

0
Xenxier

あなたはevent.currentTargetを使用することができます。クリックイベントはイベントを頂いた方のみ行います。

target = e => {
    console.log(e.currentTarget);
  };
<ul onClick={target} className="folder">
      <li>
        <p>
          <i className="fas fa-folder" />
        </p>
      </li>
    </ul>
0
Dejan Markovic