【问题标题】:How does event bubbling work on event handling?事件冒泡如何在事件处理中起作用?
【发布时间】:2019-06-03 09:16:30
【问题描述】:
我已经定义了这个事件处理程序:
document.addEventListener("load", function(){
alert("Called on page load");
}, false);
我注意到当布尔标志设置为 false 时它不会被调用(在气泡阶段触发)。有人可以帮我解释一下为什么会这样。
【问题讨论】:
标签:
javascript
addeventlistener
event-bubbling
【解决方案1】:
当一个事件被发送到一个元素时,它会在捕获阶段沿着文档树向下移动,直到它到达目标。然后,如果是冒泡事件,它会重新冒泡。
来自2.1 Introduction to “DOM Events” in the DOM standard:
当一个事件被分派给一个参与树的对象(例如一个元素)时,它也可以到达该对象的祖先上的事件侦听器。首先,按照树形顺序调用所有捕获变量设置为 true 的对象的祖先事件侦听器。其次,调用对象自己的事件侦听器。最后,并且只有当 event 的 bubbles 属性值为 true 时,才会再次调用对象的祖先事件侦听器,但现在以相反的树顺序。
load 不是冒泡事件,而且 - 这是重要的部分 - 它不针对 document。当您添加一个捕获侦听器时,您实际上会从通常接收事件的文档内容部分(如脚本或图像)中获得load 事件。在只有脚本的页面上,你根本看不到监听器被调用:
<iframe srcdoc="<script>document.addEventListener('load', () => { alert('loaded'); }, true);</script>"></iframe>
在带有load 事件的页面上,在附加侦听器后触发,例如包含<style>s 的堆栈片段,您会不止一次看到它:
let i = 0;
document.addEventListener('load', e => {
console.log(`loaded ${++i}: ${e.target.nodeName}`);
}, true);
您可能打算向window 添加一个非捕获侦听器而不是document,因为window 是接收load 事件的东西,与document 不同。 (或者你可能有别的意思。有很多方法可以解释“页面加载”。有关load 事件在window 上的含义的详细信息,请参阅Window: load event on MDN 以及如果它不是你想要的替代方案。 )
window.addEventListener("load", function() {
alert("Called on page load");
}, false);