以以下代码为例:
<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);
当我单击父元素时,我希望它执行某些操作,而当我单击子元素时,我希望它不执行任何操作。问题是,当我单击子元素时,它会触发“某些内容”。 我认为这可能是事件冒泡,这样如果我单击子元素,事件就会从那里冒泡到父元素。于是我就想到了事件捕获,但这也导致了这个问题。
任何有关如何实现这一目标的意见或建议将不胜感激。
Event.target.closest(selector)
是否确实是所需的元素选择器。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}
,也可以在应用程序级别上捕获事件,但这样做的实现并不多。
使用
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>
这是事件冒泡。仅仅因为您正在处理
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);