javascript:理解DOM事件

首先,此文不討論繁瑣細節,可是考慮到讀者的心靈感覺,本着以積極向上的心態,在此仍是會列舉示例說明。javascript

​標題爲理解DOM事件,那麼在此拿一個簡單的點擊事件爲例,但願你們看到這個例子後能舉一反三。前端

DOM事件的兼容性

最初咱們給頁面實現點擊,就像下面這樣的簡單操做。
先定義一個塊如<div id="weiyuzhou">微宇宙</div>,以後在<script type="text/javascript"></script>內部實現id爲weiyuzhou的點擊事件,以下代碼所示:java

var wyz = document.getElementById('weiyuzhou');
wyz.onclick = function () {
  confirm(arguments.length)
}

確保上面這些步驟都沒問題的話,咱們才能夠繼續的往下走,而後咱們在IE瀏覽器(低版本)看到彈出0,確切的說,IE8如下(包含IE8)的彈出0,反之彈出1。接着我在firefox瀏覽器看到彈出1。也就是說在IE8如下版本事件的觸發不存在於函數的做用域內部,是否是說IE8如下的事件觸發發生在全局做用域中,此處留個懸念,可是,能夠確定的是IE8如下事件的方法並無這個Event參數,也就是說arguments的長度爲0,以下視圖5-02所示:程序員

5-02web

因而,咱們看firefox瀏覽器窗口彈出1,說明事件存在於函數內部,再次證實方法的內部數組arguments長度爲1,而且是可枚舉的變量,也能夠說可寫,以下視圖5-03所示。數組

5-03瀏覽器

若是,你仍是不明白其中的原理,你不防去看一下《web前端開發修煉之道》書上第169頁,而後再回過頭來看此處文章摘要,可能會讓你更加深層次的瞭解書中的內容。dom

接下來,咱們該怎麼辦呢,咱們確定不能讓IE和firefox返回的事件輸出不相同,那麼如何讓IE和firefox下彈出的內容都同樣。函數

銜接上一段內容,下面給點擊函數的內部設置一個參數,參數名爲e,而後在IE和firefox瀏覽器下面同時觸發點擊事件,咱們看到firefox下面顯示e爲鼠標事件[object MouseEvent],IE8下報錯,彈出錯誤信息未定義undefined。此時你要問我錯在哪裏,我們回到剛剛的那句話‘此處留個懸念’進行分析,IE8如下的瀏覽器的事件是否是發生在全局做用域中,從視圖5-02所示看到有一個global全局對象,咱們能夠對global展開搜索,global的繼承的方法有一個event事件,找到了IE8的專有事件方法window繼承event,因而咱們對這個參數e設置爲window.event進行一個調試,目前咱們在IE8下面看到返回了一個事件[object event],如圖5-04所示。測試

5-04


想必你必定發現了IE8和firefox瀏覽器下對話框的事件返回值各不不一樣,IE8的對話框爲[object event],firefox的對話框爲[object MouseEvent],那咱們怎麼讓IE8和firefox下的返回值都相同呢?

看到這裏,你的內心是否是有點小沮喪,挖坑挖了這麼久了,怎麼尚未看到水流出來,別急,正題纔剛剛開始,我們不閒聊,繼續圍繞正題展開分析,經過剛剛的返回值,咱們繼續使用斷點的方法尋找可以實現IE和firefox的返回值的共同點。

DOM事件的冒泡

經由以上分析,咱們查找發現firefox下的event有咱們須要的方法名能夠被調用,固然,咱們查找發現IE8下面的srcElement也有咱們所需的方法名能夠被調用,因而乎,呵呵!看到這裏你的心裏是否是有點小激動,一步步排除,最後發現也沒有什麼難的。回到正題,如今咱們聲明一個變量var e_child = e.srcElement || e.target; 而後咱們在IE8和firefox瀏覽器上看到對話框信息都爲[object HTMLDivElement],如圖5-05所示。

5-05

 

 

如今咱們解決了不一樣瀏覽器的返回值不一樣的問題,也就是說解決了兼容的問題,這只是冰上一角。

下面咱們要解決實現窗口的容器觸發事件,主要是基於上面的結構進行的一次分析。

當你有了上面基礎的話,下面的內容相對於上面而言比較簡單一點。

仍是以上一個頁面的塊爲例,如今我繼續往塊<div id="weiyuzhou">微宇宙</div>增長一個子容器,這個子容器爲行內元素<span id='coz'>koringz</span>,取id名爲coz,而後給這個元素也加一個點擊事件代碼同上函數,爲了能區別開文本內容之間的差別。

當我分別在IE8和firefox下點擊容器的內容,出現了怪異的狀況,在firefox瀏覽器的窗口上點擊時,點擊中文文本內容彈出來對話框‘微宇宙’,我再點擊koringz時,發現彈出了二次對話框,彈出內容都爲'koringz',那是由於我點擊子容器的時候觸發了上一層的點擊行爲,如何解決點擊koringz彈出二次對話框的問題,瞭解一點js的程序員都知道這是冒泡事件。

那麼在firefox可以清除冒泡事件的是event下的stopPropagation,因而咱們給第二次點擊事件函數代碼塊以後面加一行代碼e.stopPropagation();以後再點擊koringz發現彈出一次'koringz'。如圖5-06所示

 5-06

接下來在IE8下面測試一下,發如今IE8瀏覽器點擊也彈出二次,解決IE8的中止冒泡事件爲cacelBubble,且咱們只須要給cacelBubble設置爲true便可。
由於IE8下global包含的event屬性cacelBubble不是一個方法,而是一個輸出布爾值的對象,因此這個和firefox有所不一樣,只是firefox把此事件封裝成方法而已。好了,如今咱們給第二次點擊的事件代碼塊以後再加一行代碼e.cancelBubble = true;而後在IE8瀏覽器下測試,以後再點擊koringz發現也彈出一次。如圖5-07所示

5-07


注意上面的中止冒泡的事件的代碼能夠根據瀏覽器的不一樣分開來寫,如何分開寫,咱們查看IE8瀏覽器下面的document發現存在對象all,而在firefox卻沒有這個all屬性,這也就是說document.all是IE8版本下面獨有的一個屬性。經過它咱們能夠區分瀏覽器的冒泡事件。

DOM事件的重用

到目前爲止,咱們解決了窗口的冒泡事件,接下來,咱們要解決一個事件因被多人定義而覆蓋原函數的問題。也多是說某公司以前的工做人員添加了此事件,後來新員工接手項目後添加修改此事件而覆蓋了原事件的執行所產生的問題。也就是說給當前id屢次添加此類事件都不會覆蓋此事件的原函數執行。

在firefox下的window包含有addEventListener(type, listener, useCapture)的方法,隨後咱們在<script type="text/javascript"></script>內部定義此監聽事件domElement.addEventListener('click',function(e){confirm(e+'e')},false);,接着在firefox瀏覽器點擊內容彈出二次,最後一次彈出爲[object MouseEvent]e,後面多了一個e,這是我有意加上用以區別的。如圖5-08所示。

 5-08


接下來在IE8下測試發現addEventListener錯誤,可是看到window下有此類方法(嘗試了一下,原來此類方法在IE9以上版本是能夠被支持),IE8同時還有一個attachEvent(event, pdisp),那麼咱們設置監聽事件wyz.attachEvent('onclick',function(e){confirm(e + 'e')}),注:event爲'onclick',緊接着在IE8下點擊發現可彈出二次,最後一次[object MouseEvent]e。此時on('click',pdisp)和attachEvent(event,pdisp)能夠共同使用。

綜上所述,咱們解決了DOM事件的兼容性,DOM事件的冒泡,以及DOM事件的重用。

相關文章
相關標籤/搜索