在DOM元素上触发的事件不仅会影响它们所针对的元素。DOM中目标的任何祖先也可能有机会对此事件做出反应。考虑以下文档:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head> <body> <p id="paragraph"> <span id="text">Hello World</span> </p> </body> </html>
如果我们仅将侦听器添加到每个元素而没有任何选项,则触发单击范围...
document.body.addEventListener('click', function(event) { console.log("身体点击了!"); }); window.paragraph.addEventListener('click', function(event) { console.log("段落已点击!"); }); window.text.addEventListener('click', function(event) { console.log("文字已点击!"); }); window.text.click();
...那么该事件将气泡向上穿过每个祖先,引发的道路上每一次点击的处理程序:
文字已点击! 段落已点击! 身体点击了!
如果您希望其中一个处理程序停止该事件触发其他任何处理程序,则可以调用该方法。例如,如果我们用以下代码替换第二个事件处理程序:event.stopPropagation()
window.paragraph.addEventListener('click', function(event) { console.log("Paragraph clicked, and that's it!"); event.stopPropagation(); });
我们将看到以下输出,其中body的click处理程序从未触发:
文字已点击! Paragraph clicked, and that's it!
最后,我们可以选择添加在“捕获”期间触发的事件侦听器,而不是冒泡的事件。在事件通过其祖先从一个元素冒起之前,它首先通过其祖先“捕获”到该元素。通过指定true或{capture: true}作为的可选第三个参数来添加捕获的侦听器addEventListener。如果将以下侦听器添加到上面的第一个示例中:
document.body.addEventListener('click', function(event) { console.log("身体点击捕获!"); }, true); window.paragraph.addEventListener('click', function(event) { console.log("段落点击捕获!"); }, true); window.text.addEventListener('click', function(event) { console.log("文字点击捕获!"); }, true);
我们将得到以下输出:
身体点击捕获! 段落点击捕获! 文字点击捕获! 文字已点击! 段落已点击! 身体点击了!
默认情况下,在冒泡阶段监听事件。要更改此设置,您可以通过在addEventListener函数中指定第三个参数来指定事件监听的阶段。(要了解有关捕获和冒泡的信息,请检查备注)
element.addEventListener(eventName, eventHandler, useCapture)
useCapture:true表示当事件在DOM树中消失时侦听事件。false表示在事件上升到DOM树时监听事件。
window.addEventListener("click", function(){alert('1: on bubble')}, false); window.addEventListener("click", function(){alert('2: on capture')}, true);
警报框将按以下顺序弹出:
2:捕获时
1:在泡沫上
Capture Event将在Bubble Event之前调度,因此,如果在捕获阶段监听某个事件,则可以确保不首先监听该事件。
如果您正在侦听父元素上的click事件,而正在侦听其子元素上的click事件,则可以根据更改useCapture参数的方式先侦听该孩子或首先侦听父事件。
在冒泡中,首先调用子事件,在捕获中,首先调用父事件
HTML:
<div id="parent"> <div id="child"></div> </div>
Javascript:
child.addEventListener('click', function(e) { alert('child clicked!'); }); parent.addEventListener('click', function(e) { alert('parent clicked!'); }, true);
将父eventListener设置为true将首先触发父侦听器。
与您结合使用可以防止事件触发子事件侦听器/或父事件。(有关下一个示例的更多信息)e.stopPropagation()