JavaScript(3)---事件冒泡、事件捕獲

JavaScript(3)---事件冒泡與事件捕獲

1、理解冒泡與捕獲

假設有這麼一段代碼javascript

<body>
  <div><p>標籤</p>
  </div>
</body>

轉換成圖以下html

咱們知道Dom是有節點關係的java

body -> div -> p 之間的關係就是  爺爺 -> 父親 -> 兒子。

咱們來思考一個關鍵的問題瀏覽器

若是此時咱們在 body div p 都綁定一個點擊事件(click)。此時若是咱們只點擊 p標籤,它會不會觸發div綁定事件body綁定事件this

答案是會的3d

那這個時候就會有一個問題,既然點擊 p標籤 會觸發 div綁定事件body綁定事件,那執行順序是怎麼樣的呢?code

body事件 -> div事件 -> p事件? 仍是  p事件  -> div事件 -> body事件?

這兩種不一樣的執行順序就是對應上面的 事件冒泡事件捕獲htm

事件捕獲 事件從最上一級標籤開始往下查找,直到捕獲到事件目標(body事件 -> div事件 -> p事件)。對象

事件冒泡 事件從事件目標開始,往上冒泡直到頁面的最上一級標籤( p事件 -> div事件 -> body事件)blog

爲了避免混淆記憶它們,這裏有個通俗的理解冒泡:

冒泡嘛,就像水裏往上冒的泡泡,從一開始很小,而後慢慢變大直到破裂。因此是從小到大,也就是子標籤到父標籤傳遞的過程。那麼事件捕獲記住與冒泡相反就能夠了。


2、事件冒泡 與 阻止冒泡

一、事件冒泡示例

代碼

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>事件冒泡</title>
  <style>
    #dv1{   /*爲了直觀 這裏添加些樣式*/
      width: 300px;
      height: 200px;
      background-color: red;
    }
    #dv2{
      width: 250px;
      height: 150px;
      background-color: green;
    }
    #dv3{
      width: 200px;
      height: 100px;
      background-color: blue;
    }
  </style>
</head>

<body>
<div id="dv1">爺爺
  <div id="dv2">父親
    <div id="dv3">兒子</div>
  </div>
</div>
<script>
  //事件冒泡:多個元素嵌套,有層次關係,這些元素都註冊了相同的事件,若是裏面的元素的事件觸發了,外面的元素的該事件自動的觸發了.
  document.getElementById("dv1").onclick=function () {
    console.log(this.id+" 爺爺");
  };
  document.getElementById("dv2").onclick=function () {
    console.log(this.id+" 父親");
  };
  //事件處理參數對象
  document.getElementById("dv3").onclick=function (e) {
    console.log(this.id+" 兒子");
    //阻止事件冒泡
    //e.stopPropagation();
  };
</script>
</body>
</html>

運行結果

從這個示例咱們能夠看出3點

一、當點擊兒子元素後,父親和爺爺的點擊事件也觸發了。
二、onclick事件的順序 兒子 - 父親 - 爺爺。
三、當點擊爺爺元素後,父親和兒子的點擊是不會觸發的。

二、阻止事件冒泡

既然有冒泡事件,那確定在實際開放過程當中,你不須要冒泡,你只想兒子點擊觸發事件,父親和爺爺不觸發事件。

語法

一、window.event.cancelBubble=true; IE特有的,谷歌支持,火狐不支持
二、e.stopPropagation(); 谷歌和火狐支持

由於我用的是谷歌瀏覽器,因此這裏用第二種方式阻止冒泡(只需把上面阻止事件冒泡的代碼取消註釋就能夠了)

運行結果

從運行結果很明顯看出,已經阻止了事件冒泡。


3、事件捕獲

示例

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>title</title>
  <style>
    #dv1 {
      width: 300px;
      height: 200px;
      background-color: red;
    }

    #dv2 {
      width: 250px;
      height: 150px;
      background-color: green;
    }

    #dv3 {
      width: 200px;
      height: 100px;
      background-color: blue;
    }
  </style>
</head>

<body>
<div id="dv1">爺爺
  <div id="dv2">父親
    <div id="dv3">兒子</div>
  </div>
</div>
<script>
    //爲每一個元素綁定事件  這裏
    /**
     * 捕獲時間 從外到裏
     * 一、 addEventListener不是每一個瀏覽器都兼容的
     * 二、 這裏true爲事件捕獲 false爲事件冒泡
     */
     document.getElementById("dv1").addEventListener("click", function (e) {
         console.log(this.id+" 爺爺");
    }, true);
   document.getElementById("dv2").addEventListener("click", function (e) {
         console.log(this.id+" 父親");
    }, true);
      document.getElementById("dv3").addEventListener("click", function (e) {
         console.log(this.id+" 兒子");
    }, true);
</script>
</body>
</html>

運行

很明顯,這裏是從外到裏執行事件。



你若是願意有所做爲,就必須善始善終。(22)