零全零美(www.zzgwt.com)
          生活中的很多事情,并不像If...Else那么簡單!
          posts - 96,comments - 52,trackbacks - 0
            如果你在頁面上做一次點擊例如點擊一個按鈕,那么你是首先點擊了該按鈕然后動作傳入了按鈕的容器,最后傳入整個頁面Document還是首先點擊了頁面Document,然后是按鈕的容器,最后導致按鈕的點擊呢?
            JavaScript對這種問題的處理方式可以稱之為事件流即事件的傳播機制。對于事件流IE跟FF有不同的解釋。IE下的解決方案稱之為:冒泡型事件,而FF下稱之為:捕獲型事件。顧名思義冒泡型事件是從低而上的觸發機制,而捕獲型事件則是從上到下的觸發機制。《JavaScript高級程序設計》一書提到:
              DOM事件流同時支持兩種事件觸發機制,但是捕獲型事件先發生。注意因為事件的目標(也就是DOM樹最深的節點)是最精確的元素,實際上它會連續接收兩次事件,一次是在捕獲過程中,一次是在冒泡過程中。
          事情到底是不是這樣呢?觀察下面的程序:
          <html onclick=" clickHandle('html'); ">
            
          <head>
              
          <title>JAVASCRIPT事件流</title>
              
          <meta http-equiv="content-type" content="text/html; charset=GBK">
              
          <script type="text/javascript">
                  
          function clickHandle(ele){
                      alert(ele);
                  }
              
          </script>
            
          </head>
            
          <body onclick=" clickHandle('body'); ">
              
          <div style="bgcolor:red" onclick=" clickHandle('div'); ">click me!</div>
            
          </body>
          </html>
          IE:點擊 click me 運行順序為:DIV-->BODY-->HTML 點擊頁面其他部分:BODY-->HTML
          FF: 點擊 click me 運行順序為:DIV-->HTML-->BODY 點擊頁面其他部分:HTML-->BODY
            呵呵,好像跟書上說的不太一樣哦!程序的運行結果告訴我們:不管是在IE下還是在FireFox下,事件總是由最精確的元素(也就是DOM樹中最深的節點)首先觸發,然后才開始IE下的冒泡和FireFox下的捕獲。

            JavaScript為我們提供了三種事件處理函數的分配方式,第一種就像上面的程序一樣,是在HTML代碼中分配事件處理函數。
          第二種方法是在JavaScript中分配事件處理函數,這種方法首先必須得獲得要分配事件處理函數的元素的引用,參考以下程序:
          1         window.onload = function(){
          2             var oDiv = document.getElementById("contentDiv");
          3             oDiv.onclick = function(){
          4                 alert(oDiv.innerHTML);
          5             }
          6         }
          就像上面提到的,該方法在分配事件處理函數時必須保證已經獲得對該元素的引用,所以這個程序才把oDiv的onclick事件放在了onload事件的內部,否則會報oDiv未被定義。還有一個需要注意的地方是使用這種事件處理函數的分配方式時只能為某個特定的事件分配一個函數且事件函數的簽名必須小寫,否則前面分配的函數會被后面的函數所覆蓋,如果想為同一個事件分配兩個以上的處理函數,需要采用第三種事件處理函數分配方式。
            在IE中我們使用obj.attachEvent()方法為某個元素分配函數,使用obj.detachEvent()方法為某個元素分離事件處理函數,而在DOM(以FireFox為例)中我們使用addEventListener()方法分配函數,使用removeEventListener()方法分離函數。
            參考一下代碼:
           1         window.onload = function(){
           2             var oDiv = document.getElementById("contentDiv");
           3             var func1 =  function(){
           4                 alert(oDiv.innerHTML);
           5             }
           6             var func2 = function(){
           7                 alert("also " + oDiv.innerHTML);
           8             }
           9             //IE
          10             if(oDiv.attachEvent){
          11                 oDiv.attachEvent("onclick",func1);
          12                 oDiv.attachEvent("onclick",func2);
          13                 //oDiv.detachEvent("onclick",func1);
          14             } else if(oDiv.addEventListener){
          15                 //FireFox
          16                 oDiv.addEventListener("click",func1,true);
          17                 oDiv.addEventListener("click",func2,true);
          18                 //oDiv.removeEventListener("click",func1,true);
          19             }
          20             
          21         }
          我們來說明一下IE下與FireFox下這種事件處理函數的不同點:
          1、在函數的第一個參數中,IE下必須有"on"做為前綴,而FF下不用,兩種情況下處理函數簽名必須小寫。
          2、FireFox下的addEventListener()函數的第三個參數表示的是:true表示在捕獲階段增加事件處理函數,false表示在冒泡階段增加事件處理函數,但是由于FireFox不支持冒泡事件流,所以這里我們設成True或者Flase好像沒什么區別。但是要注意的一點就是,如果在 addEventListener()中第三個參數設為true,那么在removeEventListener()方法中的第三個參數一定也要設為相同的值,否則方法失效。
          3、在運行時階段,IE首先執行的是最后邊一個被增加的事件處理函數然后才是倒數第二個以此類推,但是在FireFox下與IE相反,他會按照事件處理函數的添加順序執行。
          posted on 2008-07-23 09:35 零全零美 閱讀(1503) 評論(2)  編輯  收藏 所屬分類: JavaScript

          FeedBack:
          # re: JavaScript學習筆記(5)事件處理之事件流與事件處理函數分配
          2008-07-24 11:32 | 連夜雨
          看到了差距,呵呵,學習。  回復  更多評論
            
          # re: JavaScript學習筆記(5)事件處理之事件流與事件處理函數分配
          2009-01-08 10:52 | yz
          這樣的好文章,希望繼續!謝謝!  回復  更多評論
            
          主站蜘蛛池模板: 曲松县| 长兴县| 梁山县| 西充县| 徐州市| 浠水县| 南陵县| 呈贡县| 克山县| 蒲江县| 乌鲁木齐县| 永川市| 青田县| 于都县| 武乡县| 广元市| 区。| 望谟县| 白银市| 民勤县| 清原| 凌云县| 金乡县| 梅河口市| 泽州县| 九寨沟县| 紫金县| 东乌珠穆沁旗| 财经| 崇州市| 油尖旺区| 益阳市| 临城县| 谷城县| 贵州省| 柞水县| 板桥市| 蛟河市| 当阳市| 荔波县| 肇庆市|