如何让点击事件仅在父DIV上触发,而不是在子DIV上触发?

问题描述 投票:0回答:13

我有一个带有分类的

foobar
的 DIV,以及该 DIV 中的一些未分类的 DIV,但我认为它们继承了
foobar
类:

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

我希望仅在单击 DIV 中的某处而不是其子 DIV 时触发。

jquery events onclick
13个回答
530
投票

如果

e.target
this
是相同的元素,则您还没有单击后代。

$('.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>


136
投票

我没有得到公认的工作答案,但这似乎可以解决问题,至少在普通 JS 中是这样。

if(e.target !== e.currentTarget) return;

116
投票

如果您不介意只针对较新的浏览器,还有另一种可行的方法。只需添加CSS

pointer-events: none;

您想要捕获点击的 div 的任何子级。这是支持表

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


37
投票

您可以使用对您有利的冒泡:

$('.foobar').on('click', function(e) {
    // do your thing.
}).on('click', 'div', function(e) {
    // clicked on descendant div
    e.stopPropagation();
});

23
投票
//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)
});

这将停止

click
事件在
.foobar
元素的任何子元素上的传播(冒泡),因此事件不会到达要触发的
.foobar
元素他们的事件处理程序。

这是一个演示:http://jsfiddle.net/bQQJP/


6
投票

我遇到了同样的问题并提出了这个解决方案(基于其他答案)

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

基本上它表示如果目标是 div,则运行代码,否则不执行任何操作(不要隐藏它)


5
投票
$(".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
})

3
投票

您可以使用event.currentTarget。它只会执行点击事件,只有获得事件的元素。

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


2
投票

如果您无法使用

pointer-events: none;
并且针对的是现代浏览器,您可以使用
composedPath
来检测对对象的直接点击,如下所示:

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

您可以在此处阅读有关composedPath的更多信息: https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath


2
投票

定义事件时,该事件具有属性

this
。该属性表示事件被分配到的 DOMElement。要检查触发事件的元素,请使用
e.target

由于事件是在元素的子元素中继承的,因此检查目标是否

function doSomething(event) {
  if (this == event.target){
    // do something
  }
}

1
投票

我的情况类似,但这是当您有几个

foobar
-s 时,您只想关闭一个 - 每次点击:

查找家长案例

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

0
投票

// if its li get value 
document.getElementById('li').addEventListener("click", function(e) {
                if (e.target == this) {
                    UodateNote(e.target.id);
                }
                })
                
                
                function UodateNote(e) {

    let nt_id = document.createElement("div");
    // append container to duc.
    document.body.appendChild(nt_id);
    nt_id.id = "hi";
    // get conatiner value . 
    nt_id.innerHTML = e;
    // body...
    console.log(e);

}
li{
 cursor: pointer;
    font-weight: bold;
  font-size: 20px;
    position: relative;
    width: 380px;
    height: 80px;
    background-color: silver;
    justify-content: center;
    align-items: center;
    text-align: center;
    margin-top: 0.5cm;
    border: 2px solid purple;
    border-radius: 12%;}
    
    p{
     cursor: text;
  font-size: 16px;
   font-weight: normal;
    display: block;
    max-width: 370px;
    max-height: 40px;
    overflow-x: hidden;}
<li id="li"><p>hi</p></li>


0
投票
$('.foobar').on('click', function(e) {
  var el = e.target;
  if (e.target !== this) {
    el = e.target.closest('DIV');
  }

  
  alert( 'clicked the foobar' );
});
© www.soinside.com 2019 - 2024. All rights reserved.