Pau*_*son 4 html javascript dom addeventlistener
以以下代码为例:
<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);
Run Code Online (Sandbox Code Playgroud)
当我单击父元素时,我希望它执行某些操作,而当我单击子元素时,我希望它不执行任何操作。问题是,当我单击子元素时,它会触发“某些内容”。我认为这可能是事件冒泡,这样如果我单击子元素,事件就会从那里冒泡到父元素。于是我就想到了事件捕获,但这也导致了这个问题。
任何有关如何实现这一目标的意见或建议将不胜感激。
相反,仅将事件添加到父元素,并检查发起事件的元素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) Closing some opened popup, etc");
});
// and BODY should always be notified about events! And this works as expected.Run Code Online (Sandbox Code Playgroud)
#parent, #child {
padding: 1rem;
outline: 1px solid red;
}Run Code Online (Sandbox Code Playgroud)
<div id="parent">
<b>PARENT</b> ELEMENT
<div id="child">CHILD ELEMENT</div>
</div>Run Code Online (Sandbox Code Playgroud)
不要使用Event.stopPropagation()
Event.stopPropagation()这将是一个想法,但却是一个糟糕的想法。我们应该避免应用程序层不注册 DOM 树更深处发生的事件。我们应该让事件自由冒泡,并最终通知其他元素此类事件发生了。
想象一下,body监听点击事件以关闭最近打开的自定义下拉菜单、模式等。如果您的应用程序中存在使用的元素,则Event.stopPropagation()单击这样的元素,打开的下拉菜单将不会关闭,从而导致UI 损坏。这只是一个简单的例子。
当然,即使组件使用事件捕获阶段,也可以在应用程序级别捕获事件,但这样做的开发人员并不多。Event.stopPropagation(){capture: true}
这是一种不推荐的(!)使用方法Event.stopPropagation(),但仍然可以捕获应用程序级别的事件:
const elParent = document.querySelector("#parent");
const elChild = document.querySelector("#child");
function doChildStuff(evt) {
evt.stopPropagation(); // DISCOURAGED. Avoid
console.log("Do child stuff only");
}
function doParentStuff(evt) {
console.log("Do parent stuff");
}
elChild.addEventListener("click", doChildStuff);
elParent.addEventListener("click", doParentStuff);
// Additional example: proper planning for `Event.stopPropagation()`:
document.body.addEventListener("click", () => {
console.log("(App was notified) Closing some opened popup, etc");
}, {capture: true}); // PROPER WAY, since we use Event.stopPropagation()Run Code Online (Sandbox Code Playgroud)
#parent, #child {
padding: 1rem;
outline: 1px solid red;
}Run Code Online (Sandbox Code Playgroud)
<div id="parent">
<b>PARENT</b> ELEMENT
<div id="child">CHILD ELEMENT</div>
</div>Run Code Online (Sandbox Code Playgroud)
用于event.stopPropagation停止事件冒泡:
function something() {
console.log("something");
}
document.getElementById('parent').addEventListener('click', something);
document.getElementById('child').addEventListener('click', e => e.stopPropagation());Run Code Online (Sandbox Code Playgroud)
<div id="parent">
Parent info goes here!
<div id="child">Child info goes here!</div>
</div>Run Code Online (Sandbox Code Playgroud)