DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> 理解javascript中DOM事件
理解javascript中DOM事件
編輯:關於JavaScript     

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

​標題為理解DOM事件,那麼在此拿一個簡單的點擊事件為例,希望大家看到這個例子後能觸類旁通。
最初我們給頁面實現點擊,就像下面這樣的簡單操作。
先定義一個塊如<div id="weiyuzhou">微宇宙</div>,之後在<script type="text/javascript"></script>內部實現id為weiyuzhou的點擊事件,如下代碼所示:

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所示:

於是,我們看firefox浏覽器窗口彈出1,說明事件存在於函數內部,再次證明方法的內部數組arguments長度為1,並且是可枚舉的變量,也可以說可寫,如下視圖所示。

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

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

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


想必你一定發現了IE8和firefox浏覽器下對話框的事件返回值各不不同,IE8的對話框為[objectevent],firefox的對話框為[objectMouseEvent],那我們怎麼讓IE8和firefox下的返回值都相同呢?

看到這裡,你的心裡是不是有點小沮喪,挖坑挖了這麼久了,怎麼還沒有看到水流出來,別急,正題才剛剛開始,咱們不閒聊,繼續圍繞正題展開分析,通過剛剛的返回值,我們繼續使用斷點的方法尋找能夠實現IE和firefox的返回值的共同點。

經由以上分析,我們查找發現firefox下的event有我們需要的方法名可以被調用,當然,我們查找發現IE8下面的srcElement也有我們所需的方法名可以被調用,於是乎,呵呵!看到這裡你的內心是不是有點小激動,一步步排除,最後發現也沒有什麼難的。回到正題,現在我們聲明一個變量vare_child=e.srcElement||e.target;然後我們在IE8和firefox浏覽器上看到對話框信息都為[objectHTMLDivElement],如圖所示。

現在我們解決了不同浏覽器的返回值不同的問題,也就是說解決了兼容的問題,這只是冰上一角。

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

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

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

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

那麼在firefox能夠清除冒泡事件的是event下的stopPropagation,於是我們給第二次點擊事件函數代碼塊之後面加一行代碼e.stopPropagation();之後再點擊koringz發現彈出一次'koringz'。如圖所示

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


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

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

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


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

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

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved