JavaScript事件機制——細思極恐

JavaScript事件機制,也有讓人深思的東西。在一開始未深刻了解,我頭腦裏有幾個問題發出:javascript

1. 自下而上(冒泡)事件怎麼寫,自上而下(捕獲)又是怎麼寫?php

2. 捕獲型和冒泡型同時設置,誰生效?html

3. 冒泡可以阻止,那捕獲可以阻止嗎?java

4. jquery的on或bind是冒泡,仍是捕獲?jquery

5. 兩種事件方式的應用場景是?this

示例spa

<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8"/>
<title>Events</title>
<script type="text/javascript" src="jquery-3.0.0.js"></script>
<style>
     html,body{
          width:100%;
          height:100%;
          padding: 0;
          margin: 0;
     }
     div{
          float:left;
          width: 200px;
          height:200px;
          border:1px solid blue;
     }
     p{
          width: 100px;
          height:100px;
          border:1px solid red;
     }
</style>
</head>
     <body id="body">
          <div id="J_d0">
               0<p id="J_p0"></p>
          </div>
          <div id="J_d1">
               1<p id="J_p1"></p>
          </div>
          <div id="J_d2">
               2<p id="J_p2"></p>
          </div>
          <div id="J_d3">
               3<p id="J_p3"></p>
          </div>
          <div id="J_d4">
               4<p id="J_p4"></p>
          </div>
     </body>
     <script>
          var body = document.getElementById('body');
          body.addEventListener('click', hello, true); //當爲false時,所有在最後執行。
 
          bindEvent_d_p(0,true,true);
          //點擊p,輸出
          //i am body
          //i am J_d0
          //i am J_p0
 
          bindEvent_d_p(1,false,true);
          //點擊p,輸出
          //i am body
          //i am J_p1
          //i am J_d1
 
          bindEvent_d_p(2,false,false);
          //點擊p,輸出
          //i am body
          //i am J_p2
          //i am J_d2
 
          bindEvent_d_p(3,true,false);
          //點擊p,輸出
          //i am body
          //i am J_d3
          //i am J_p3
 
          $("#J_d4").on("click", hello);
          $("#J_p4").on("click", hello);
          //點擊p,輸出
          //i am body
          //i am J_p4
          //i am J_d4
 
          function bindEvent_d_p(index, d_useCapture, p_useCapture){
               var d = document.getElementById('J_d'+index);
               var p = document.getElementById('J_p'+index);
               
//第三個參數,指定事件是在捕獲階段仍是冒泡階段執行。
d.addEventListener('click', hello, d_useCapture);
p.addEventListener('click', hello, p_useCapture);
 } function hello() { console.log("i am " + this.id); } </script>
</html>

這裏關鍵的是第三個參數。W3CSchool解釋爲「指定事件是否在捕獲或冒泡階段執行」,我以爲這個說明會讓人誤會,搞得像捕獲或冒泡均可以不選的樣子。但其實不是,只是二選一,因此最好解釋爲「指定事件是在捕獲階段仍是冒泡階段執行」。.net

定義code

JavaScript的事件是以一種流(迴環流)的形式存在的,一個事件會有多個元素同時響應。以下圖:htm

PS:圖例來自http://www.nowamagic.net/javascript/js_EventAnalysis.php

這個圖很是清楚的說明的事件的執行順序,徹底能夠解釋示例中的結果。事件一直從window往觸發目標元素流,當父或祖先捕獲事件時,就先執行,否則就在冒泡階段執行,直到window。

Q&A

1. 自下而上(冒泡)事件怎麼寫,自上而下(捕獲)又是怎麼寫?

當須要冒泡時,第三參數設爲false就行;

當須要捕獲時,第三參數設爲true就行;

2. 捕獲型和冒泡型同時設置,誰生效?

按第三參數的設置,只有二選一,並不存在能夠同時設置狀況。

3. 冒泡可以阻止,那捕獲可以阻止嗎?

冒泡事件是可以阻止,e.stopPropagation();,你們是比較清楚的,一樣的捕獲事件也是能阻止的。

其實就是當先觸發的事件是在捕獲過程的,阻止了事件傳播,就是捕獲阻止,當在冒泡過程當中阻止,就是冒泡阻止。

結果就是,事件流再也不繼續流了,不管是往下仍是往上。

4. jquery的on或bind是冒泡,仍是捕獲?

通過上面示例能夠驗證, jquery的on或bind是冒泡執行的。

另外在jquery3.0.0的源碼4943行地方:

// Init the event handler queue if we're the first
if ( !( handlers = events[ type ] ) ) {
     handlers = events[ type ] = [];
     handlers.delegateCount = 0;

     // Only use addEventListener if the special events handler returns false
    if ( !special.setup ||
         special.setup.call( elem, data, namespaces, eventHandle ) === false ) {

         if ( elem.addEventListener ) {
               elem.addEventListener( type, eventHandle );
         }
    }
}

這裏能夠很明顯看到,事件的註冊並無傳第三個參數,因此 jquery的on或bind確定是冒泡執行的。

5. 兩種事件方式的應用場景是?

額,這個問題並很差回答,就具體問題,具體分析了。

 

總結

小小的往細處想,居然發現我其實有些細節並沒明白,共勉。


本文爲原創文章,轉載請保留原出處,方便溯源,若有錯誤地方,謝謝指正。

本文地址 :http://www.cnblogs.com/lovesong/p/5705541.html

相關文章
相關標籤/搜索