434

我目前正在使用 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>
4

25 回答 25

549

事件冒泡到 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();
});
于 2009-09-02T17:26:13.400 回答
120

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

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

正如jQuery Docs所说:

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

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

于 2009-09-02T17:24:37.413 回答
65

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

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

如果单击父母的孩子,您的代码将不会被执行

于 2015-04-07T18:53:19.843 回答
25

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

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

在你的情况下:

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

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

.clickable * {
    pointer-events: none;
}

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

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

于 2017-05-04T09:07:13.410 回答
17

你也可以试试这个

$("#clickable").click(function(event) {
   var senderElementName = event.target.tagName.toLowerCase();
   if(senderElementName === 'div')
   {
       // do something here 
   } 
   else
   {
      //do something with <a> tag
   }
});
于 2015-08-16T10:50:46.730 回答
13

内联替代方案:

<div>
    <!-- Other content. -->
    <a onclick='event.stopPropagation();' href="http://foo.com">I don't want #clickable to handle this click event.</a>
</div>
于 2019-07-23T01:41:01.470 回答
10

写如果有人需要(为我工作):

event.stopImmediatePropagation()

这个解决方案。

于 2016-07-26T10:42:23.873 回答
8

如果可点击 div 中有多个元素,则应执行以下操作:

$('#clickable *').click(function(e){ e.stopPropagation(); });
于 2012-08-11T10:15:32.213 回答
8

使用return false;ore.stopPropogation();将不允许进一步的代码执行。它会在此时停止流动。

于 2015-04-15T15:27:09.250 回答
5

我比较ev.currentTarget什么时候this不可用(React 等)。

$("#clickable").click(function(e) {
    if (e.target === e.currentTarget) {
        window.location = url;
        return true;
    }
})
于 2021-04-13T05:18:32.290 回答
3

这是使用 Angular 2+ 的示例

例如,如果您想在用户单击模态组件外部时关闭它:

// Close the modal if the document is clicked.

@HostListener('document:click', ['$event'])
public onDocumentClick(event: MouseEvent): void {
  this.closeModal();
}

// Don't close the modal if the modal itself is clicked.

@HostListener('click', ['$event'])
public onClick(event: MouseEvent): void {
  event.stopPropagation();
}
于 2017-08-25T18:16:49.840 回答
3

var inner = document.querySelector("#inner");
var outer = document.querySelector("#outer");
inner.addEventListener('click',innerFunction);
outer.addEventListener('click',outerFunction);

function innerFunction(event){
  event.stopPropagation();
  console.log("Inner Functiuon");
}

function outerFunction(event){
  console.log("Outer Functiuon");
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Pramod Kharade-Event with Outer and Inner Progration</title>
</head>
<body>
<div id="outer" style="width:100px;height:100px;background-color:green;">
  <div id="inner" style="width:35px;height:35px;background-color:yellow;"></div>
</div>
</body>
</html>

于 2018-10-11T04:29:02.043 回答
2

如果它是在内联上下文中,在 HTML 中试试这个:

onclick="functionCall();event.stopPropagation();
于 2020-06-14T23:32:08.597 回答
2

e.stopPropagation()是一个正确的解决方案,但如果您不想将任何事件处理程序附加到您的内部锚点,您可以简单地将这个处理程序附加到您的外部 div:

e => { e.target === e.currentTarget && window.location = URL; }
于 2020-07-11T22:51:29.423 回答
1

您需要阻止事件到达(冒泡)父级(div)。请参阅此处有关冒泡的部分,以及此处的 jQuery 特定 API 信息。

于 2009-09-02T17:27:27.157 回答
1

您可以检查目标是否不是您的 div 元素,然后在父级上发出另一个单击事件,之后您将从句柄“返回”。

$('clickable').click(function (event) {
    let div = $(event.target);
    if (! div.is('div')) {
       div.parent().click();
       return;
    }
    // Then Implement your logic here
}
于 2020-07-15T16:57:16.250 回答
1

这是一个对我有用的非 jQuery 解决方案。

<div style="background:cyan; width:100px; height:100px;" onclick="if (event.srcElement==this) {console.log('outer');}">
    <a style="background:red" onclick="console.log('inner');">Click me</a>
</div>

于 2021-02-16T20:36:57.140 回答
0

要将某些子元素指定为不可点击,请编写 css 层次结构,如下例所示。

在此示例中,我停止传播到具有类“.subtable”的表内的 td 内 tr 内的任何元素 (*)

$(document).ready(function()
{    
   $(".subtable tr td *").click(function (event)
   {
       event.stopPropagation();
   });

});
于 2014-01-16T14:18:09.953 回答
0

如果有人在使用 React 时遇到了这个问题,我就是这样解决的。

scss:

#loginBackdrop {
position: absolute;
width: 100% !important;
height: 100% !important;
top:0px;
left:0px;
z-index: 9; }

#loginFrame {
width: $iFrameWidth;
height: $iFrameHeight;
background-color: $mainColor;
position: fixed;
z-index: 10;
top: 50%;
left: 50%;
margin-top: calc(-1 * #{$iFrameHeight} / 2);
margin-left: calc(-1 * #{$iFrameWidth} / 2);
border: solid 1px grey;
border-radius: 20px;
box-shadow: 0px 0px 90px #545454; }

组件的渲染():

render() {
    ...
    return (
        <div id='loginBackdrop' onClick={this.props.closeLogin}>
            <div id='loginFrame' onClick={(e)=>{e.preventDefault();e.stopPropagation()}}>
             ... [modal content] ...
            </div>
        </div>
    )
}

通过为子模式(内容 div)添加 onClick 函数,可以防止鼠标单击事件到达父元素的“closeLogin”函数。

这对我有用,我能够用 2 个简单的 div 创建模态效果。

于 2018-08-25T06:17:48.867 回答
0

ignoreParent()是一个纯 JavaScript 解决方案。

它作为一个中间层,将鼠标点击的坐标与子元素的坐标进行比较。两个简单的实现步骤:

1.将 ignoreParent() 代码放在您的页面上。

2.代替父级原来的onclick="parentEvent();" , 写:

onclick="ignoreParent(['parentEvent()', 'child-ID']);"

您可以将任意数量的子元素的 ID 传递给函数,并排除其他元素。

如果您单击其中一个子元素,则不会触发父事件。如果您单击了父元素,但没有单击任何子元素 [作为参数提供],则会触发父事件。

Github 上的 ignoreParent() 代码

于 2019-05-16T15:16:24.630 回答
0

如果单击子元素,则事件会冒泡到父元素和 event.target !== event.currentTarget。

因此,在您的函数中,您可以检查并提前返回,即:

var url = $("#clickable a").attr("href");
$("#clickable").click(function(event) {
    if ( event.target !== event.currentTarget ){
        // user clicked on a child and we ignore that
        return;
    }
    window.location = url;
    return true;
})
于 2020-11-05T16:20:23.117 回答
-1

这就是你要找的

mousedown事件。这适用于每个 DOM 元素,以防止像这样的 javascript 焦点处理程序:

$('.no-focus').mousedown(function (e) {
   e.prevenDefault()

   // do stuff
}

vue.js框架中,您可以像这样使用修饰符:

<span @mousedown.prevent> no focus </span>

请注意,在输入上使用将阻止文本选择处理程序

于 2021-04-30T09:16:02.737 回答
-3

添加a如下:

<a href="http://foo.com" onclick="return false;">....</a>

return false;来自点击处理程序,#clickable例如:

  $("#clickable").click(function() {
        var url = $("#clickable a").attr("href");
        window.location = url;
        return false;
   });
于 2009-09-02T17:27:20.620 回答
-3

所有的解决方案都很复杂并且属于 jscript。这是最简单的版本:

var IsChildWindow=false;

function ParentClick()
{
    if(IsChildWindow==true)
    {
        IsChildWindow==false;
        return;
    }
    //do ur work here   
}


function ChildClick()
{
    IsChildWindow=true;
    //Do ur work here    
}
于 2011-02-23T06:44:54.647 回答
-5
<a onclick="return false;" href="http://foo.com">I want to ignore my parent's onclick event.</a>
于 2009-09-02T17:25:13.807 回答