document.getElementById('form').addEventListener("click", e => alert('Capturing en form'), true)
document.getElementById('form').addEventListener("click", e => alert('Bubbling en form'))
document.getElementById('div').addEventListener("click", e => alert('Capturing en div'), true)
document.getElementById('div').addEventListener("click", e => alert('Bubbling en div'))
document.getElementById('objetivo').addEventListener("click", e => alert('Capturing en el objetivo'), true)
document.getElementById('objetivo').addEventListener("click", e => alert('Bubbling en el objetivo'))
window.onload = function() {
var c = document.getElementById("c");
var a = document.getElementById("a");
var b = document.getElementById("b");
c.addEventListener("click", f1, true);
b.addEventListener("click", f2, true);
a.addEventListener("click", f3, true);
}
function f1() {
console.log("has pulsado en el boton C");
}
function f2() {
console.log("has pulsado en la B")
}
function f3() {
console.log("has pulsado en la A")
}
window.onload = function() {
var c = document.getElementById("c");
var a = document.getElementById("a");
var b = document.getElementById("b");
c.addEventListener("click", f1);
b.addEventListener("click", f2);
a.addEventListener("click", f3);
}
function f1() {
console.log("has pulsado en el boton C");
}
function f2() {
console.log("has pulsado en la B")
}
function f3() {
console.log("has pulsado en la A")
}
冒泡表示从执行 event(
event.target
) 的元素传播到层次结构中具有相同事件的最远元素的事件。也就是从事件的源头到最远的祖先:请注意事件是如何首先执行的
p
,然后是div
最后执行的form
。那是冒泡。要停止冒泡,请使用以下方法
event#stopPropagation()
:至于捕获,它与冒泡相反:不是执行从源到祖先的事件,而是从祖先到源。
例如,看看这里如何定义 2 个事件,1 个用于 the
form
,1 个用于p
. 请注意单击元素如何p
首先执行 的事件form
然后转到p
,而单击 时form
,仅执行其事件:您可能已经注意到,冒泡是默认事件。如果要使用捕获,则只需将其
true
作为最后一个参数传递给addEventListener
.关于用例,始终建议使用冒泡,因为它是发现触发事件的元素位置的最简单方法。我从来没有见过使用捕获的必要性,而且你肯定有它的原因,默认情况下它会冒泡。
在 JavaScript 中,当事件在 DOM 元素上执行时,有 3 个不同的阶段按以下顺序执行:
让我们看一个冒泡的例子,如果我们有一个捕获相同类型事件的元素层次结构,它们将从目标元素激活到父元素:
如您所见,如果我们单击目标元素,则首先激活警报,然后是 Div,最后在 Form 中,这是冒泡的,从目标到父级。
现在我们进行捕获,这是相反的方向,我们可以使用
addEventListener(evento, manejador[, capturing])
元素上的函数看到它在操作中,让我们看一个例子:在第二个示例中,我们通过将true作为 addEventListener 中的第三个参数添加到捕获事件中,我们可以看到事件的执行顺序,首先捕获,从父元素到目标元素,然后再返回. 气泡,从目标到父级。
所有这一切都有很多优点,具体取决于您希望在代码中实现的目标,捕获由于其从父节点到子节点的性质而未被广泛使用,但是冒泡是非常重要的事情,我们必须考虑到在 JavaScript 中使用事件,因为传播到元素
document
会导致我们不想要的东西。我留给你这篇Javascript.info的优秀帖子,它是英文的,但它以更详细的方式解释了事件的传播、如何阻止它以及我们必须了解每个事件的属性。
捕获和冒泡之间的区别
冒泡从深处穿过太阳树
捕获与冒泡相反
冒泡示例
捕获的示例