如何解决DOM Event.StopPropagation对子对象无效
我正在做一个有关事件的教程,并且被Event.StopPropagation()
方法所困扰。以我的示例看来,对孩子的冒泡影响正在受到影响。
StopPropagation
的定义:
起初我以为是浏览器问题,但事实并非如此。我找不到有关此问题的解决方案。
代码:
// Event Bubbling and Propagation
// element.addEventListener( type,func,useCapture);
let m = document.getElementById('m');
let d = document.getElementById('d');
let p = document.getElementById('p');
let s = document.getElementById('s');
let highlight = (ev)=>{
//add CSS class "gold" to the clicked element
ev.stopPropagation();
let target = ev.currentTarget;
target.className = 'gold';
reset(target);
}
let reset = (_element)=>{
setTimeout(()=>{
_element.className = '';
},2000);
}
d.addEventListener('click',(ev)=>{
ev.stopImmediatePropagation();
log('Hi I\'m a DIV');
});
[m,d,p,s].forEach((element)=>{
element.addEventListener('click',highlight);
})
#m,#d,#p,#s{
border: 2px solid black;
padding: 15px;
margin: 10px;
}
.gold{
background-color: gold;
}
<main id="m"> m
<div id="d"> d
<p id="p"> p
<span id="s"> s</span>
</p>
</div>
</main>
解决方法
这不是事件的问题,您对此太想了。
您的示例只是将背景颜色应用于顶部元素,并且由于未定义子级,因此将背景颜色应用于其下方。
如果您删除stopImmediatePropagation()
,颜色将被应用,因为定义如下:执行第一个事件处理程序,并停止执行其余的事件处理程序,第一个是只需log()
。
在下面的示例中,如果将背景色应用于子元素,则会看到它们将保持不变。自身的颜色仅应用于单击的颜色。
这意味着JS事件本身没有冒泡到父元素或捕获下来。并且仅在单击的一个上添加了类。使用开发工具进行检查或在每个元素上添加DOM更改事件侦听器。
您将CSS样式与JS事件冒泡混淆了。
示例:
// Event Bubbling and Propagation
// element.addEventListener( type,func,useCapture);
let m = document.getElementById('m');
let d = document.getElementById('d');
let p = document.getElementById('p');
let s = document.getElementById('s');
let log = console.log;
let highlight = (ev)=>{
//add CSS class "gold" to the clicked element
ev.stopPropagation();
let target = ev.currentTarget;
target.className = 'gold';
reset(target);
}
let reset = (_element)=>{
setTimeout(()=>{
_element.className = '';
},2000);
}
d.addEventListener('click',(ev)=>{
//ev.stopImmediatePropagation();
log('Hi I\'m a DIV');
});
[m,d,p,s].forEach((element)=>{
element.addEventListener('click',highlight);
})
#m,#d,#p,#s{
border: 2px solid black;
padding: 15px;
margin: 10px;
}
#d {
background-color: blue;
}
#s {
background-color: red;
}
.gold{
background-color: gold !important;
}
<main id="m"> m
<div id="d"> d
<p id="p"> p
<span id="s"> s</span>
</p>
</div>
</main>
编辑:
在您的示例子节点中,它没有背景属性(rgba(0,0)
),这意味着您需要在单击时进行设置,以便被单击元素的背景颜色不会应用于其子元素。
在下面的代码中,您可以读取单击的父元素的CSS背景值,并读取其background属性。您将其应用于所有已单击的子项。
这将在您的示例中起作用。 如果父对象是透明的,还可以确保将白色应用于元素。
这是一个玩弄的小提琴: 但请确保取消注释m(父级)背景色以查看副作用。您需要对此进行调整以适合您的生产需求
const style = getComputedStyle(target.parentNode);
const backgroundColor = style.backgroundColor;
console.clear();
console.log(backgroundColor);
[...target.children].forEach(el => {
if (backgroundColor==="rgba(0,0)") {
el.style.backgroundColor = "white";
}else{
el.style.backgroundColor = backgroundColor;}
})
// Event Bubbling and Propagation
// element.addEventListener( type,useCapture);
let m = document.getElementById('m');
let d = document.getElementById('d');
let p = document.getElementById('p');
let s = document.getElementById('s');
let log = console.log;
let highlight = (ev)=>{
//add CSS class "gold" to the clicked element
ev.stopPropagation();
let target = ev.currentTarget;
target.className = 'gold';
const style = getComputedStyle(target.parentNode);
const backgroundColor = style.backgroundColor;
console.clear();
console.log(backgroundColor);
[...target.children].forEach(el => {
if (backgroundColor==="rgba(0,0)") {
el.style.backgroundColor = "white";
}else{
el.style.backgroundColor = backgroundColor;}
})
reset(target);
}
let reset = (_element)=>{
setTimeout(()=>{
_element.className = '';
},2000);
}
[m,#s{
border: 2px solid black;
padding: 15px;
margin: 10px;
}
#m {
background-color: blue;
}
.gold{
background-color: gold !important;
}
<main id="m"> m
<div id="d"> d
<p id="p"> p
<span id="s"> s</span>
</p>
</div>
</main>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。