<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>capture and bubble</title>
<style type="text/css">
#child{
background: red;
width:50px;
height:50px;
}
#father{
width:100px;
height:100px;
background:green;
}
</style>
</head>
<body>
<div id='father'>
<div id='child'></div>
</div>
</body>
<script type="text/javascript">
var parent = document.getElementById("father");
var child = document.getElementById('child');
var html = document.getElementsByTagName("html")[0];
var body = document.body;
parent.addEventListener("click",function() {
console.log("I am capturing parent");
},true);
parent.addEventListener("click",function() {
console.log("I am parent");
},false);
child.addEventListener("click",function() {
console.log("I am capturing child");
},true);
child.addEventListener("click",function() {
console.log("I am child");
},false);
body.addEventListener("click",function() {
console.log("I am capturing body");
},true);
body.addEventListener("click",function() {
console.log("I am body");
},false);
html.addEventListener("click",function() {
console.log("I am capturing html");
},true);
html.addEventListener("click",function() {
console.log("I am html");
},false);
parent.addEventListener("click",function() {
console.log("I am capturing parent");
},true);
parent.addEventListener("click",function() {
console.log("I am parent");
},false);
</script>
</html>
For the above html containning a js to display executing order of capture and bubble,i have binded two listeners of capture and bubble two times for the parent(div father),one pair of capture and bubble for the parent(div father) is from 5th line till 10th line in the js script part; other pair of capture and bubble for the parent(div father) is at the ending of the js script part.
Click the green div(father div),get the result in console.
test.html:50 I am capturing html
test.html:44 I am capturing body
test.html:32 I am capturing parent
test.html:35 I am parent
test.html:56 I am capturing parent
test.html:59 I am parent
test.html:47 I am body
test.html:53 I am html
Why the result is not the following?
test.html:50 I am capturing html
test.html:44 I am capturing body
test.html:32 I am capturing parent
test.html:56 I am capturing parent
test.html:35 I am parent
test.html:59 I am parent
test.html:47 I am body
test.html:53 I am html
Please explain it in detail.
The MDN documentation for addEventListener
states:
Note: For event listeners attached to the event target, the event is in the target phase, rather than the capturing and bubbling phases. Events in the target phase will trigger all listeners on an element in the order they were registered, regardless of the
useCapture
parameter.
This is what happens here. The event listeners are attached to the event target (parent
in your example), therefore the event is in the target phase and the listeners are triggered in the order they were registered.
Note that if you click child
, this doesn't happen because the event is in capture or bubbling phase. The result as expected is:
I am capturing html
I am capturing body
I am capturing parent
I am capturing parent
I am capturing child
I am child
I am parent
I am parent
I am body
I am html
There is a good explanation and diagram of the event flow here.