1. 程式人生 > >DOM事件階段以及事件捕獲與事件冒泡先後執行順序

DOM事件階段以及事件捕獲與事件冒泡先後執行順序

DOM事件三個階段

當一個DOM事件被觸發時,它不僅僅只是單純地在本身物件上觸發一次,而是會經歷三個不同的階段:

  1. 捕獲階段:先由文件的根節點document往事件觸發物件,從外向內捕獲事件物件;
  2. 目標階段:到達目標事件位置(事發地),觸發事件;
  3. 冒泡階段:再從目標事件位置往文件的根節點方向回溯,從內向外冒泡事件物件。

引用來源:http://www.w3.org/TR/DOM-Level-3-Events/#event-flow

事件捕獲與事件冒泡先後執行順序就顯而易見了。

實驗部分

 開啟線上編輯器:http://JSbin.com/goqede/edit?html,CSS,js,output

程式碼如下:

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Document</title>
     <style>
         #outer{
             text-align: center;
             width: 400px;
             height: 400px;
             background-color: #ccc;
             margin: 0 auto;
         }
         #middle{
             width: 250px;
             height: 250px;
             background-color: #f00;
             margin: 0 auto;
         }
         #inner{
             width: 100px;
             height: 100px;
             background-color: #0f0;
             margin: 0 auto;
             border-rad
         }
     </style>
 </head>
 <body>
     <div id='outer'>
         <span>outer</span>
         <div id='middle'>
             <span>middle</span>
             <div id='inner'>
                 <span>inner</span>
             </div>
         </div>
     </div>
     <script>
         function $(element){
             return document.getElementById(element);
         }
         function on(element,event_name,handler,use_capture){
             if(addEventListener){
                 $(element).addEventListener(event_name,handler,use_capture);
             }
             else{
                 $(element).attachEvent('on'+event_name,handler);
             }
         }
 
         on("outer","click",o_click_c,true);
         on("middle","click",m_click_c,true);
         on("inner","click",i_click_c,true);
 
         on("outer","click",o_click_b,false);
         on("middle","click",m_click_b,false);
         on("inner","click",i_click_b,false);
         
         
 
         function o_click_c(){
             console.log("outer_捕獲");
             alert("outer_捕獲");
         }
         function m_click_c(){
             console.log("middle_捕獲")
             alert("middle_捕獲");
         }
         function i_click_c(){
             console.log("inner_捕獲")
             alert("inner_捕獲");
         }
         function o_click_b(){
             console.log("outer_冒泡")
             alert("outer_冒泡");
         }
         function m_click_b(){
             console.log("middle_冒泡")
             alert("middle_冒泡");
         }
         function i_click_b(){
             console.log("inner_冒泡")
             alert("inner_冒泡");
         }
     </script>
 </body>
 </html>

當我們點選inner的時候結果是:

outer_捕獲
middle_捕獲
inner_捕獲
inner_冒泡
middle_冒泡
outer_冒泡

由此可見:確實是先由外向內事件捕獲,一直到事發元素,在由內向外冒泡到根節點上

tips:

當事件觸發在目標階段時,會根據事件註冊的先後順序執行,在其他兩個階段註冊順序不影響事件執行順序。也就是說如果該處既註冊了冒泡事件,也註冊了捕獲事件,則按照註冊順序執行。

 例如當我點選inner的時候,按照以上順序,答案確實是我們想要的答案:

當我的事件註冊順序改變成如下程式碼時:

當我們點選outer時:

當我們點選middle時:

當我們點選inner時:

可以看出在目標階段的事發元素上的事件執行順序是有事件註冊順序決定的

本文地址:http://www.cnblogs.com/alvinwei1024/p/4739344.html