单击子锚点时,如何防止触发父级的 onclick 事件?

IT技术 javascript jquery event-propagation
2021-01-27 06:52:38

我目前正在使用 jQuery 使 div 可点击,在这个 div 中我也有锚点。我遇到的问题是,当我点击一个锚点时,两个点击事件都会触发(对于 div 和锚点)。单击锚点时,如何防止 div 的 onclick 事件触发?

这是损坏的代码:

JavaScript

var url = $("#clickable a").attr("href");

$("#clickable").click(function() {
    window.location = url;
    return true;
})

HTML

<div id="clickable">
    <!-- Other content. -->
    <a href="http://foo.com">I don't want #clickable to handle this click event.</a>
</div>
6个回答

事件冒泡到 DOM 中已附加单击事件的最高点。因此,在您的示例中,即使 div 中没有任何其他明确可点击的元素,div 的每个子元素也会将它们的点击事件向上冒泡到 DOM,直到 DIV 的点击事件处理程序捕获它。

对此有两种解决方案,即检查事件的真正发起者是谁。jQuery 将 eventargs 对象与事件一起传递:

$("#clickable").click(function(e) {
    var senderElement = e.target;
    // Check if sender is the <div> element e.g.
    // if($(e.target).is("div")) {
    window.location = url;
    return true;
});

您还可以将点击事件处理程序附加到您的链接,告诉他们在他们自己的处理程序执行后停止事件冒泡

$("#clickable a").click(function(e) {
   // Do something
   e.stopPropagation();
});
很好的答案。很高兴知道也有选择。
2021-03-20 06:52:38
+1!使用 stopPropagation 附加点击处理程序是一个非常好的技巧,谢谢!
2021-03-23 06:52:38
if( e.target !== this) return;检查放入父级意味着如果单击该父级的任何其他没有自己的 onClick 处理程序的子级,则什么也不会发生。因此,对于例如可点击的父 div 的情况,它是无用的。e.stopPropagation()但是工作正常。
2021-04-05 06:52:38
如果你有一堆想要阻止传播的元素,你可以找到它们的父元素并阻止它在那里冒泡。因此,与其拦截 div 中的所有 a 链接,让我们说例如——只需拦截 div 本身的点击,并防止它变得更高,然后你就设置好了。
2021-04-08 06:52:38
if( e.target !== this) return;在父级中使用e.stopPropagation()在子级中使用更好,因为您永远不知道其他人是否将某个处理程序附加到子项,或者库是否必须将处理程序附加到子项(并且您不想弄乱库代码)。这是更好的关注点分离。
2021-04-09 06:52:38

使用stopPropagation方法,看一个例子:

$("#clickable a").click(function(e) {
   e.stopPropagation();
});

正如jQuery Docs所说:

stopPropagation 方法可防止事件在 DOM 树中冒泡,从而防止任何父处理程序收到该事件的通知。

请记住,它不会阻止其他侦听器处理此事件(例如,一个按钮的多个单击处理程序),如果这不是您想要的效果,则必须stopImmediatePropagation改用。

小心,以免您不小心将事件侦听器设置为被动
2021-03-14 06:52:38

这是我为寻找非 jQuery 代码(纯 javascript)的每个人提供的解决方案

document.getElementById("clickable").addEventListener("click", function( e ){
    e = window.event || e; 
    if(this === e.target) {
        // put your code here
    }
});

如果点击父母的孩子,你的代码不会被执行

很好的答案。我只是直接通过了事件。所以我没有使用window.eventMDN 不鼓励的:developer.mozilla.org/en-US/docs/Web/API/Window/event如果您能抽出时间,如果您能评论您使用的原因,我将不胜感激window.event(也许这是 2015 年存在的问题,或者我未能理解原因)。
2021-03-14 06:52:38
这对我有用,我需要一个非 JS/jQuery 解决方案。10 倍!
2021-03-30 06:52:38

如果您不打算在任何情况下与内部元素进行交互,那么 CSS 解决方案可能对您有用。

只需将内部元素设置为 pointer-events: none

在你的情况下:

.clickable > a {
    pointer-events: none;
}

或一般针对所有内部元素:

.clickable * {
    pointer-events: none;
}

在使用 ReactJS 进行开发时,这个简单的 hack 为我节省了大量时间

浏览器支持可以在这里找到:http : //caniuse.com/#feat=pointer-events

你也可以试试这个

$("#clickable").click(function(event) {
   var senderElementName = event.target.tagName.toLowerCase();
   if(senderElementName === 'div')
   {
       // do something here 
   } 
   else
   {
      //do something with <a> tag
   }
});