据我了解,DOM Level 2 事件处理按以下顺序工作:
- 从顶部 HTML 元素一直捕获到目标之前
- 目标本身
- 一直冒泡回到顶部的 HTML 元素
示例位于:https
://jsfiddle.net/uwe5dmxw/
(我将在此问题末尾包含代码)
但是,如果我在当前的 Google Chrome、Firefox、Safari 甚至 IE 11 上单击“子”元素(最低级别的后代),我会按以下顺序得到一致的结果:
- HTML 捕获
- 身体捕捉
- 父捕获
- 目标冒泡
- 目标捕获
- 父冒泡
- 身体冒泡
- HTML 冒泡
即,“目标捕获”和“目标冒泡”的顺序颠倒了。
据我了解,虽然 DOM Level 2 表示事件仅到达目标一次,但大多数浏览器将其实现为两次到达,一次是在事件捕获期间,一次是在事件冒泡期间。但事实是,为什么“目标捕获”和“目标冒泡”是相反的?
代码:(不过只是个demo,没必要不用看)
<div id="hi">
hello
<div id="child">
child
</div>
</div>
JavaScript:
var parentElement = document.getElementById("hi"),
childElement = document.getElementById("child"),
htmlElement = document.getElementsByTagName("html")[0],
bodyElement = document.getElementsByTagName("body")[0];
// ------------------ Bubble --------------------
htmlElement.addEventListener("click", function() {
console.log("<html> clicked " + new Date().getTime(), this);
});
bodyElement.addEventListener("click", function() {
console.log("<body> clicked " + new Date().getTime(), this);
});
parentElement.addEventListener("click", function() {
console.log("Parent clicked " + new Date().getTime(), this);
});
childElement.addEventListener("click", function() {
console.log("Child clicked at " + new Date().getTime(), this);
});
// ------------------ Use Capture --------------------
htmlElement.addEventListener("click", function() {
console.log("<html> (useCapture) clicked " + new Date().getTime(), this);
}, true);
bodyElement.addEventListener("click", function() {
console.log("<body> (useCapture) clicked " + new Date().getTime(), this);
}, true);
parentElement.addEventListener("click", function() {
console.log("Parent (useCapture) clicked " + new Date().getTime(), this);
}, true);
childElement.addEventListener("click", function() {
console.log("Child (useCapture) clicked at " + new Date().getTime(), this);
}, true);