仅在父级点击而非子级点击时触发事件

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

以以下代码为例:

<div id="parent">
  <div id="child">info goes here</div>
</div>

//javascript
function something{
//do something;}
//initial attempt
document.getElementById('parent').addEventListener('click',something);
//event capture
document.getElementById('parent').addEventListener('click',something,true);

当我单击父元素时,我希望它执行某些操作,而当我单击子元素时,我希望它不执行任何操作。问题是,当我单击子元素时,它会触发“某些内容”。 我认为这可能是事件冒泡,这样如果我单击子元素,事件就会从那里冒泡到父元素。于是我就想到了事件捕获,但这也导致了这个问题。

任何有关如何实现这一目标的意见或建议将不胜感激。

javascript html dom addeventlistener
3个回答
8
投票

相反,仅将事件添加到父元素,并检查发起事件的元素

Event.target.closest(selector)
是否确实是所需的元素选择器
PS:
不要将
Event.target
Event.currentTarget 混淆,后者(相反)始终是附加了事件处理程序的元素。

const elParent = document.querySelector("#parent");

function doStuff(evt) {
  if (evt.target.closest("#child")) {
    console.log("Do child stuff only");
  } else {
    console.log("Do parent stuff only (not if child is clicked)");
  }
}

elParent.addEventListener("click", doStuff);

// Additional example on why you should avoid `Event.stopPropagation()`:
document.body.addEventListener("click", () => console.log("(App was notified)"));
// and BODY should always be notified about events! And this works as expected.
#parent, #child {
  padding: 1rem;
  outline: 1px solid red;
}
<div id="parent">
  <b>PARENT</b> ELEMENT
  <div id="child">CHILD ELEMENT</div>
</div>

请勿使用

Event.stopPropagation()

Event.stopPropagation()
将是一个想法,但是一个糟糕的想法。我们应该避免应用程序层不注册 DOM 树更深处发生的事件。我们应该让事件自由冒泡 - 并最终通知其他元素此类事件发生了。
想象一个
body
监听点击事件,以便关闭最近打开的自定义下拉菜单、模式等。如果您的应用程序中存在使用
Event.stopPropagation()
的元素 - 单击此类元素,打开的下拉菜单将不会关闭,从而导致在损坏的用户界面中。这只是一个简单的例子。
当然,即使组件通过使用事件捕获阶段Event.stopPropagation()使用
{capture: true}
,也可以在
应用程序级别
上捕获事件,但这样做的实现并不多。


4
投票

使用

event.stopPropagation
停止事件冒泡:

function something() {
  console.log("something");
}
document.getElementById('parent').addEventListener('click', something);
document.getElementById('child').addEventListener('click', e => e.stopPropagation());
<div id="parent">
  Parent info goes here!
  <div id="child">Child info goes here!</div>
</div>


0
投票

这是事件冒泡。仅仅因为您正在处理

child
上的单击事件,并不意味着它会停止向父级冒泡。

对此有两种方法。第一个是阻止事件传播,如下所示:

document.getElementById('child').addEventListener('click',(e) => { e.stopPropagation(); something() },true);

第二种是检查事件目标,只有当引起点击事件的最深元素是子元素时才运行

something

document.getElementById('child').addEventListener('click',(e) => { e.target.id == "child" ? something() : nothing() },true);

© www.soinside.com 2019 - 2024. All rights reserved.