鍍金池/ 問(wèn)答/Java  HTML/ 為何捕獲事件和冒泡事件執(zhí)行了兩次?

為何捕獲事件和冒泡事件執(zhí)行了兩次?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>事件冒泡</title>
  <style type="text/css">
  #child{
    background: red;
    width:50px;
    height:50px;
  }
  #father{
    width:100px;
    height:100px;
    background:green;
  }
  #grandparent{
    width:150px;
    height:150px;
    background:black;
    margin:100px auto 0;
  }
  </style>
</head>
<body>
  <div id='grandparent'>
    <div id='father'>
      <div id='child'></div>
    </div>
  </div>
</body>
<script type="text/javascript">
  var grandparent = document.getElementById("grandparent");
  var parent = document.getElementById("father");
  var child = document.getElementById('child');
  var html = document.getElementsByTagName("html")[0];
  var body = document.body;
  grandparent.addEventListener("click",function () {
    console.log("I am capturing grandparent");
  },true);
  grandparent.addEventListener("click",function () {
    console.log("I am grandparent");
  },false);
  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);
  document.addEventListener("click",function() {
    console.log("I am capturing document");
  },true);
  document.addEventListener("click",function() {
    console.log("I am document");
  },false);
  window.addEventListener("click",function() {
    console.log("I am capturing window");
  },true);
  window.addEventListener("click",function() {
    console.log("I am window");
  },false);
  parent.addEventListener("click",function() {
    console.log("I am capturing parent");
  },true);
   parent.addEventListener("click",function() {
    console.log("I am parent");
  },false);
</script>
</html>

注意:我將

  parent.addEventListener("click",function() {
    console.log("I am capturing parent");
  },true);
   parent.addEventListener("click",function() {
    console.log("I am parent");
  },false);
  

上面的兩行代碼重復(fù)了兩次,一次在中間,一次在末尾。

點(diǎn)擊緑色的div,得到下面的結(jié)果:

test.html:75 I am capturing window
test.html:69 I am capturing document
test.html:63 I am capturing html
test.html:57 I am capturing body
test.html:39 I am capturing grandparent
test.html:45 I am capturing parent
test.html:48 I am parent
test.html:81 I am capturing parent
test.html:84 I am parent
test.html:42 I am grandparent
test.html:60 I am body
test.html:66 I am html
test.html:72 I am document
test.html:78 I am window

為何結(jié)果不是
test.html:75 I am capturing window
test.html:69 I am capturing document
test.html:63 I am capturing html
test.html:57 I am capturing body
test.html:39 I am capturing grandparent
test.html:45 I am capturing parent
test.html:48 I am parent
test.html:42 I am grandparent
test.html:60 I am body
test.html:66 I am html
test.html:72 I am document
test.html:78 I am window

或者

test.html:75 I am capturing window
test.html:69 I am capturing document
test.html:63 I am capturing html
test.html:57 I am capturing body
test.html:39 I am capturing grandparent
test.html:45 I am capturing parent
test.html:81 I am capturing parent
test.html:48 I am parent
test.html:84 I am parent
test.html:42 I am grandparent
test.html:60 I am body
test.html:66 I am html
test.html:72 I am document
test.html:78 I am window

請(qǐng)解釋?

回答
編輯回答
冷溫柔
  1. 事件觸發(fā)流程是捕獲 -> 目標(biāo) -> 冒泡,不管你是否監(jiān)聽或者監(jiān)聽?zhēng)状危录紩?huì)觸發(fā),你監(jiān)聽只是綁定了事件的回調(diào)函數(shù),并不影響事件的觸發(fā)。所以監(jiān)聽2次必然會(huì)執(zhí)行兩次
  2. 由于測(cè)試的代碼測(cè)試的是點(diǎn)擊目標(biāo),在目標(biāo)階段可以理解為捕獲和冒泡是一致的,所以先綁定的先執(zhí)行,后綁定的后執(zhí)行。如果你把代碼測(cè)試到點(diǎn)擊元素的父元素,會(huì)得到期望的結(jié)果
2017年8月26日 10:28
編輯回答
我甘愿

事件監(jiān)聽是兩次。所以事件執(zhí)行也是兩次。

2018年9月9日 19:36
編輯回答
笑忘初

應(yīng)該是click事件處理函數(shù)的隊(duì)列里的冒泡和捕獲是放在一起的,所以你添加的順序是,捕獲,冒泡,捕獲,冒泡,所以它執(zhí)行的時(shí)候就是按這個(gè)順序執(zhí)行。

2018年6月2日 21:49
編輯回答
奧特蛋

找了半天才發(fā)現(xiàn),哥們你給 parent 添加了兩次事件,能不執(zhí)行兩次嗎!

2017年1月2日 19:59