天天看點

javascript事件處理在IE和FireFox中的差別

    如果在使用javascript的時候涉及到event處理,就需要知道event在不同的浏覽器中的差異,因為javascript的事件模型有三種,它們分别是NN4、IE4+和W3C/Safari;這也造成了在不同的浏覽器中處理event的差異,這裡結合一些零碎的代碼來說明如何做到event在IE4+和Firefox下的正常工作。

一個事件其實在頁面上有多個元素相應事件處理,點選頁面上的一個button,會發生什麼?其實 是相當于先後點選了按鈕,它的容器,及這個頁面.也就是說沒一個元素都按照特定的順序響應那個事件.事件的發生順序在IE和mozilla在事件支援上的主要差别.

  事件流

   冒泡技術.冒泡型事件的基本思想,事件按照從特定的事件目标開始到最不确定的事件目标.例如:

    <html>

        <head>

            test

        <body onclick="handle()">

             <div onclick="handle1()">click</div>

        </body>

    </html>

  IE5.5順序是div  --body--document.

在IE6中div-body--html--document.

mozilla的順序是div--body--html--html--document--window.

  還有另外一種技術:捕獲型事件,它的執行順序正好和冒泡技術相反,從document開始到div結束.

DOM事件流

     同時支援2種事件,但是捕獲型事件先發生.2種事件流會觸及DOM中的所有對象,從document開始,也在document結束.DOM事件流最獨特的性質是,文本節點也會觸發事件(在IE不會),是以如果點選click, dom事件是這樣的:

  首先window--document--body--div--click.

  然後click--div--body--document--window.

是以一個事件處理函數在DOM浏覽器中會執行2次.

給事件指定處理函數  的做法比較簡單

var obj = document.getElementById("id");

obj.onclick=function(){}

或者直接在html标簽裡加onclick="function-name"

這兩種方式是在目前所有流行的浏覽器種都可以使用.但是如何為每個事件配置設定多個處理函數呢?

IE的做法:

   在IE  中,每個元素和window對象都有2個方法:attachEvent()和detachEvent(); attachEvent用來給一個事件附加事件處理函數. 而detachEvent用來将事件處理函數分離.每個方法都有2個參數:要配置設定的事件處理函數的名字(例如:onclick)和一個函數引用.

例如:

var fnClick=function(){alert("ss")}

var fnClick1=function(){alert("sss")}

var obj=document.getElementById("id")

obj.attachEvent("onclick",fnClick);

obj.attachEvent("onclick",fnClick1);

obj.detachEvent("onclick",fnClick);

事件的執行順序是按照添加的順序執行的.

DOM方法

     dom中對應的方法是addEventListener()和removeEventListener ,這兩個方法有3個參數,事件名稱,要配置設定的函數和處理函數是用于冒泡階段還是捕獲階段.如果事件處理函數是用在捕獲階段,第三個參數為true,冒泡階段為false.用法和IE中的用法一樣,不再多說了,就舉一個例子吧:

obj.addEventListener("click",fnClick,false);

obj.addEventListener("click",fnClick1,false);

obj.removeEventListener("click",fnClick,false);

注意這裡的是事件名稱"click",不是要配置設定的事件處理函數的名字"onclick",自己體會一下吧.

如何擷取事件對象:

    擷取事件資訊是很重要的事情,事件對象隻在事件發生時被建立,而且隻有在事件處理函數中可以通路,當所有的事件處理函數結束後,事件對象被銷毀.

IE和DOM在擷取事件對象上也是有差别的.

IE中,事件對象時window的一個屬性event,也就是說必須在事件處理函數中這樣通路:

obj.onclick=function(){obj 1= window.event;}

盡管它是window的屬性,event對象也是隻能在事件發生時通路.

DOM的準則說明,event對象必須座位唯一的參數傳遞給事件處理函數,是以在DOM浏覽器中通路對象有兩種方法:

1.obj.onclick=function(){obj1=arguments[0]}

2.obj.onclick=function(envent){}

事件的屬性:介紹幾個比較常用的

IE:

altKey                 boolean                                          true 按下alt健

button                 integer                                            0=未按鍵,

                                                                                1=按下左鍵,

                                                                                2=右健,

                                                                                3=同時按左右,

                                                                                4=按下中鍵,

                                                                                5=左鍵+中鍵,

                                                                                6=右鍵+中鍵,

                                                                                7=三個健子一起按下

cancelBuble          boolean                                            設定成true 會停止事件向上冒泡.

fromElement         element                                         滑鼠事件中,滑鼠所離開的元素.

srcElement                                                                引起事件的元素

toElement                                                                  滑鼠事件中,滑鼠所進入的元素

type                      string                                           事件的名稱.

DOM中:

bubbles                boolean                                         表示事件是否是否在冒泡階段中

cancelable            ''                                                    表示事件能否取消.

charCode                                                                   按下健的unicode值,和IE的keyCode不一樣

currentTarget                                                             事件目前所指向的元素

detail                    integer                                            滑鼠點按鈕被點選的次數

eventPhase           integer                                            1=捕獲階段,2=在目标上,3=冒泡階段

isChar                  Boolean                                          表示按鍵是否時字元

preventDefault       Function                                       調用這個方法可以終止事件的預設行為

relatedTaget                                                               事件的第二個目标,經常使用者滑鼠事件.

stopPropagation                                                      調用這個方法,組織事件将來事件的冒泡.

首先看如下代碼:

function doEventThing(eventTag){    

   var event = eventTag||window.event;    

   var currentKey = event.charCode||event.keyCode;    

   var eventSource =window.event.srcElement||eventTag.target;    

}  

       這段代碼主要是為了處理鍵盤事件的,在IE中event作為window對象的一個屬性可以直接使用,但是在Firefox中卻使用了W3C的模型,它是通過傳參的方法來傳播事件的,也就是說你需要為你的函數提供一個事件響應的接口,在上述函數中,

eventTag扮演的就是這個角色。

             var event = eventTag||window.event;

             這段代碼可以根據浏覽器的不同來得到正确的event,并在程式中使用,如果在IE4+下面使用這段代碼,因為eventTag為null可以保證event = window.event,但是如果在Firefox下運作的話則因為手工的給定了eventTag是以var event = eventTag。根據對這一段代碼的分析我們也不難看出可以對doEventThing方法進行如下的改造(因為javascript允許我們在定義function的時候不明确指出參數的數量):

function doEventThing(){    

    var event = arguments[0]||window.event;    

     //other code    

在Firefox下arguments[0]在特定的場合(沒有顯式的指定function參數數量的時候)被做為傳播事件的參數來使用…………

      至于var currentKey = event.charCode||event.keyCode;也是不同的浏覽器所緻,在IE4+下面記錄鍵盤的是keyCode,但是在Firefox下的卻是charCode,為此我們需要處理他們的差異。

     還有一個差異就是事件源的擷取:通過語句var eventSource = window.event.srcElement||eventTag.target;我們也看到了IE與W3C的不同。

     經過上面的包裝,我們基本上可以在IE4+和Firefox下面順利的使用事件機制了,當然如果為了通用性可以對這種差異進封裝來形成自己的Event對象在程式中誤差别的使用事件對象,這裡就不在介紹了。

     接下來分析事件的綁定:大概分為如下5種

     1、綁定到元素,這也是比較常見的一種比如:

<input type="button" onclick="doEventThing(event)">  

,這樣我們就把doEventThing綁定到了該button對象上,點選此按鈕事件就被觸發。

    2、綁定事件到對象:這也是比較常見的一種,特别是在IE4+下面:

                 document.getElementById("divid").onclick = doEventThing;

   3、使用<script for>進行事件的綁定,這隻在IE4+下有用(為buttong1綁定事件,邏輯在script塊中書寫event來指定怎麼觸發事件):

                 <script event="onclick" for="button1">

                     // script statements here

                  </script>

   4、使用 IE5/Windows 的 attachEvent() 方法    

   5、使用 W3C DOM 的 addEventListener() 方法

              addEventListener("eventType",listenerReference,captureFlag);

              第三個參數則是一個 Boolean 值,指明該結點是否以DOM中所謂的捕捉模式來偵聽事件。對于一個典型的事件偵聽器來說,第三個參數應該為false(假)。

  prototype在綁定事件的時候相容IE和W3C的時候做的處理如下:

_observeAndCache: function(element, name, observer, useCapture) {    

   if (!this.observers) this.observers = [];    

   if (element.addEventListener) {//W3C DOM    

     this.observers.push([element, name, observer, useCapture]);    

     element.addEventListener(name, observer, useCapture);    

   } else if (element.attachEvent) {//IE5/Windows    

     element.attachEvent('on' + name, observer);    

   }    

撇開this.observers.pust([element,name,observer,useCapture])不談,我們對4、5所說的事件綁定就很清楚了。我們知道prototype的此方法的useCapture在IE下沒有作用,隻對W3C的事件處理機制起作用。

撇開this.observers.pust([element,name,observer,useCapture])不談,我們對4、5所說的事件綁定就很清楚了。我們知道prototype的此方法的useCapture在IE下沒有作用,隻對W3C的事件處理機制起作用

繼續閱讀