DOM Event.StopPropagation 到 child 没有效果
DOM Event.StopPropagation to child has no effect
我正在做一个关于事件的教程,但我坚持使用 Event.StopPropagation()
方法。在我的示例中,children 的冒泡效果似乎受到了影响。
StopPropagation
的定义:
The stopPropagation() method prevents propagation of the same event from being called.
Propagation means bubbling up to parent elements or capturing down to child elements.
一开始以为是浏览器的问题,其实不是。我找不到解决方案。
代码:
// 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>
这不是事件的问题,你想多了。
你的例子只是将背景颜色应用到顶部元素,由于 children 没有定义它,它应用它下面的顶部元素。
并且如果您删除 stopImmediatePropagation()
颜色将应用,因为定义是:执行第一个事件处理程序,并停止执行其余的事件处理程序,第一个只是 log()
.
在下面的示例中,如果您将背景颜色应用于 child 元素,您会发现它们将保持不变。它自己的颜色仅应用于单击的颜色。
这意味着 JS 事件本身没有向上冒泡到 parent 个元素或向下捕获。并且 class 仅在单击一个时添加。使用开发工具检查它或在每个元素上添加 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>
编辑:
在你的例子中 child 节点没有背景 属性 (rgba(0, 0, 0, 0)
),这意味着你需要在点击时设置它,这样被点击元素的背景颜色就不会应用children.
在下面的代码中,您可以读取被单击元素的 parent 元素的 CSS 背景值,并读取其背景 属性。你把它应用到所有 children 的点击。
这将适用于您的示例。
如果 parent 是 transparent.
,您还可以确保将白色应用于元素
这里有一个 fiddle 可以玩:
但请确保您将 un-comment m (parent) 背景颜色查看副作用。您需要对此进行调整以满足您的生产需求
const style = getComputedStyle(target.parentNode);
const backgroundColor = style.backgroundColor;
console.clear();
console.log(backgroundColor);
[...target.children].forEach(el => {
if (backgroundColor==="rgba(0, 0, 0, 0)") {
el.style.backgroundColor = "white";
}else{
el.style.backgroundColor = backgroundColor;}
})
// 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';
const style = getComputedStyle(target.parentNode);
const backgroundColor = style.backgroundColor;
console.clear();
console.log(backgroundColor);
[...target.children].forEach(el => {
if (backgroundColor==="rgba(0, 0, 0, 0)") {
el.style.backgroundColor = "white";
}else{
el.style.backgroundColor = backgroundColor;}
})
reset(target);
}
let reset = (_element)=>{
setTimeout(()=>{
_element.className = '';
}, 2000);
}
[m,d,p,s].forEach((element)=>{
element.addEventListener('click', highlight);
})
#m,#d,#p,#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>
我正在做一个关于事件的教程,但我坚持使用 Event.StopPropagation()
方法。在我的示例中,children 的冒泡效果似乎受到了影响。
StopPropagation
的定义:
The stopPropagation() method prevents propagation of the same event from being called. Propagation means bubbling up to parent elements or capturing down to child elements.
一开始以为是浏览器的问题,其实不是。我找不到解决方案。
代码:
// 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>
这不是事件的问题,你想多了。
你的例子只是将背景颜色应用到顶部元素,由于 children 没有定义它,它应用它下面的顶部元素。
并且如果您删除 stopImmediatePropagation()
颜色将应用,因为定义是:执行第一个事件处理程序,并停止执行其余的事件处理程序,第一个只是 log()
.
在下面的示例中,如果您将背景颜色应用于 child 元素,您会发现它们将保持不变。它自己的颜色仅应用于单击的颜色。
这意味着 JS 事件本身没有向上冒泡到 parent 个元素或向下捕获。并且 class 仅在单击一个时添加。使用开发工具检查它或在每个元素上添加 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>
编辑:
在你的例子中 child 节点没有背景 属性 (rgba(0, 0, 0, 0)
),这意味着你需要在点击时设置它,这样被点击元素的背景颜色就不会应用children.
在下面的代码中,您可以读取被单击元素的 parent 元素的 CSS 背景值,并读取其背景 属性。你把它应用到所有 children 的点击。
这将适用于您的示例。 如果 parent 是 transparent.
,您还可以确保将白色应用于元素这里有一个 fiddle 可以玩: 但请确保您将 un-comment m (parent) 背景颜色查看副作用。您需要对此进行调整以满足您的生产需求
const style = getComputedStyle(target.parentNode);
const backgroundColor = style.backgroundColor;
console.clear();
console.log(backgroundColor);
[...target.children].forEach(el => {
if (backgroundColor==="rgba(0, 0, 0, 0)") {
el.style.backgroundColor = "white";
}else{
el.style.backgroundColor = backgroundColor;}
})
// 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';
const style = getComputedStyle(target.parentNode);
const backgroundColor = style.backgroundColor;
console.clear();
console.log(backgroundColor);
[...target.children].forEach(el => {
if (backgroundColor==="rgba(0, 0, 0, 0)") {
el.style.backgroundColor = "white";
}else{
el.style.backgroundColor = backgroundColor;}
})
reset(target);
}
let reset = (_element)=>{
setTimeout(()=>{
_element.className = '';
}, 2000);
}
[m,d,p,s].forEach((element)=>{
element.addEventListener('click', highlight);
})
#m,#d,#p,#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>