亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

搜索

JavaScript事件機(jī)制——細(xì)思極恐

原創(chuàng) 2016-11-11 13:13:39 396
摘要:JavaScript事件機(jī)制,也有讓人深思的東西。在一開(kāi)始未深入了解,我頭腦里有幾個(gè)問(wèn)題發(fā)出:1. 自下而上(冒泡)事件怎么寫,自上而下(捕獲)又是怎么寫?2. 捕獲型和冒泡型同時(shí)設(shè)置,誰(shuí)生效?3. 冒泡能夠阻止,那捕獲能夠阻止嗎?4. jquery的on或bind是冒泡,還是捕獲?5. 兩種事件方式的應(yīng)用場(chǎng)景是?示例<!DOCTYPE HTML> <html

JavaScript事件機(jī)制,也有讓人深思的東西。在一開(kāi)始未深入了解,我頭腦里有幾個(gè)問(wèn)題發(fā)出:

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

2. 捕獲型和冒泡型同時(shí)設(shè)置,誰(shuí)生效?

3. 冒泡能夠阻止,那捕獲能夠阻止嗎?

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

5. 兩種事件方式的應(yīng)用場(chǎng)景是?

示例

<!DOCTYPE HTML>
<html>
<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); //當(dāng)為false時(shí),全部在最后執(zhí)行。
 
          bindEvent_d_p(0,true,true);
          //點(diǎn)擊p,輸出
          //i am body
          //i am J_d0
          //i am J_p0
 
          bindEvent_d_p(1,false,true);
          //點(diǎn)擊p,輸出
          //i am body
          //i am J_p1
          //i am J_d1
 
          bindEvent_d_p(2,false,false);
          //點(diǎn)擊p,輸出
          //i am body
          //i am J_p2
          //i am J_d2
 
          bindEvent_d_p(3,true,false);
          //點(diǎn)擊p,輸出
          //i am body
          //i am J_d3
          //i am J_p3
 
          $("#J_d4").on("click", hello);
          $("#J_p4").on("click", hello);
          //點(diǎn)擊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);
               
               //第三個(gè)參數(shù),指定事件是在捕獲階段還是冒泡階段執(zhí)行。
               d.addEventListener('click', hello, d_useCapture);
               p.addEventListener('click', hello, p_useCapture);
          }
          function hello() {
               console.log("i am " + this.id);
          }
     </script>
</html>

這里關(guān)鍵的是第三個(gè)參數(shù)。W3CSchool解釋為“指定事件是否在捕獲或冒泡階段執(zhí)行”,我覺(jué)得這個(gè)說(shuō)明會(huì)讓人誤會(huì),搞得像捕獲或冒泡都可以不選的樣子。但其實(shí)不是,只是二選一,所以最好解釋為“指定事件是在捕獲階段還是冒泡階段執(zhí)行”。

定義

JavaScript的事件是以一種流(回環(huán)流)的形式存在的,一個(gè)事件會(huì)有多個(gè)元素同時(shí)響應(yīng)。如下圖:

QQ截圖20161111131339.png

這個(gè)圖非常清楚的說(shuō)明的事件的執(zhí)行順序,完全可以解釋示例中的結(jié)果。事件一直從window往觸發(fā)目標(biāo)元素流,當(dāng)父或祖先捕獲事件時(shí),就先執(zhí)行,不然就在冒泡階段執(zhí)行,直到window。

Q&A

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

當(dāng)需要冒泡時(shí),第三參數(shù)設(shè)為false就行;

當(dāng)需要捕獲時(shí),第三參數(shù)設(shè)為true就行;

2. 捕獲型和冒泡型同時(shí)設(shè)置,誰(shuí)生效?

按第三參數(shù)的設(shè)置,只有二選一,并不存在可以同時(shí)設(shè)置情況。

3. 冒泡能夠阻止,那捕獲能夠阻止嗎?

冒泡事件是能夠阻止,e.stopPropagation();,大家是比較清楚的,同樣的捕獲事件也是能阻止的。

其實(shí)就是當(dāng)先觸發(fā)的事件是在捕獲過(guò)程的,阻止了事件傳播,就是捕獲阻止,當(dāng)在冒泡過(guò)程中阻止,就是冒泡阻止。

結(jié)果就是,事件流不再繼續(xù)流了,無(wú)論是往下還是往上。

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

經(jīng)過(guò)上面示例可以驗(yàn)證, jquery的on或bind是冒泡執(zhí)行的。

另外在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 );
         }
    }
}

這里可以很明顯看到,事件的注冊(cè)并沒(méi)有傳第三個(gè)參數(shù),所以 jquery的on或bind肯定是冒泡執(zhí)行的。

5. 兩種事件方式的應(yīng)用場(chǎng)景是?

額,這個(gè)問(wèn)題并不好回答,就具體問(wèn)題,具體分析了。


發(fā)布手記

熱門詞條