如何在子元素被点击时防止触发点击处理程序?

10

我有两个div标签,第一个div是父元素,第二个div是子元素,位于父元素内部,如下所示:

<div id="father"> 
<div id="son"> </div>
</div>

我在父级div中添加了一个onclick事件,代码如下:

<div id="father" onclick="closeFather()"> 
<div id="son"> </div>
</div>

我的问题是为什么儿子继承了父亲的事件。

我希望当我点击父元素时实现事件,但当我点击子元素时不执行任何操作,因为它没有任何事件。

5个回答

9

这是由JavaScript特性引起的,叫做事件冒泡。默认情况下,事件会“冒泡”到DOM中。

当点击子节点时,你会自动触发它的父节点的点击事件。

默认情况下,当点击一个元素时,从内向外冒泡:这意味着首先触发子元素的click()事件,然后是它的父元素等。

你可以通过为子元素添加第二个点击处理程序,并告诉浏览器以跨浏览器兼容的方式停止冒泡来解决问题,如下所示(查看实时示例):

<script language="javascript">
    function parentHandler(e) {
        alert('parent clicked');
    };

    function childHandler(e) {
        if (!e) var e = window.event;
        e.cancelBubble = true;
        if (e.stopPropagation) e.stopPropagation();    

        alert('child clicked');

    };    
</script>

<div id="parent" onclick="parentHandler(event);">
    Foo
    <div id="child" onclick="childHandler(event)">
        Bar
    </div>
</div>

1
你的例子中问题仍然存在。 - Lion King
2
了解事件从内向外冒泡的原理非常重要!谢谢 :) - Wylliam Judd

8
您可以将事件作为 closeFather 函数的参数之一传递,然后检查事件目标是否为父元素。请参见此示例
function closeFather(e) {
    if(e.target == document.getElementById('father')) {
        //do stuff
    }
};

然后在HTML中,您只需要将事件参数添加到JavaScript函数中即可。
<div id="father" onclick="closeFather(event)">
<div id="son"></div>
</div>

1
这是错误的,并且无法正常工作。请参见 示例 - Aron Rotteveel
奇怪。你用的是什么浏览器?我快速测试了一下,在Chrome中运行良好。请参考这个例子 - Connell
@Connell Watkins - 但在实践中并不可行。 - Lion King
你是什么意思?我想你有比这更多的代码。在父元素内是否有其他你想要继承事件的div元素?如果你只是想让事件不在点击子元素时触发,你可以使用 if(e.target != document.getElementById('son')) - Connell
@Connell Watkins - 这段代码适用于现代浏览器,但不适用于IE7和IE6。 - Lion King
我认为IE使用e.srcElement而不是e.target。请尝试改用if((e.target || e.srcElement) == document.getElementById('father')) - Connell

2

这是事件冒泡。它是DOM事件的核心部分。如果事件由son触发,您可以在处理程序中(closeFather,但是您应该将事件传递给它)return false并防止冒泡。


1
使用CSS禁用事件!
.parent-element .element{
   pointer-events: none;
}

当将此CSS属性设置为“none”时,元素将不会接收悬停/点击事件,而是事件将发生在其后面的任何内容上。

https://caniuse.com/?search=pointer-events


0
奇怪的是,我通过在子元素上同时调用event.preventDefault()和event.stopPropagation()来解决了同样的问题,冒泡行为消失了!希望能对你有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接