javascript
javascript中0级DOM和2级DOM事件模型浅析
Javascript程序使用的是事件驅動的設計模式,為一個元素添加事件監聽函數,當這個元素的相應事件被觸發那么其添加的事件監聽函數就被調用:
<input type="button" οnclick="alert('Button Click')" />
當上面的button被點擊后,會彈出一個框顯示“Button Click”.
在javascript中添加事件監聽函數有多種方法,比如:
在html元素上?
用上述元素對應的js屬性?
用統一的添加函數?
??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ????
這幾種方法在作用域,事件傳播等方面都有區別,這就是所謂的0級DOM,2級DOM事件模型的區別。讓我們來看下何謂0級DOM,2級DOM。
0級DOM:?
一開始瀏覽器處理事件的時候只有原始事件模型,事件處理程序被設置為js代碼串作為html的性質值,例如:
[xhtml]?view plaincopy
在js中html元素都有一個對應的對象,這個對象的屬性對應那個html元素的性質,所以可以用js代碼添加事件監聽函數
[javascript]?view plaincopy
通常情況下事件監聽函數如果返回一個值并且是false,則會阻止瀏覽器執行默認的動作。無論用html還是js,都是把一個函數賦值給文檔元素,在事件監聽函數被調用時候它是作為產生事件的元素的放法調用的,所以this引用的是那個目標元素(例子中的Input對象)。
從技術上來說,W3C的DOM標準并不支持上述最原始的添加事件監聽函數的方式,這些都是在DOM標準形成前的事件模型。盡管沒有正式的W3C標準,但這種事件模型仍然得到廣泛應用,這就是我們通常所說的0級DOM。?
2級DOM:?
DOM級別1于1998年10月1日成為W3C推薦標準。1級DOM標準中并沒有定義事件相關的內容,所以沒有所謂的1級DOM事件模型。在2級DOM中除了定義了一些DOM相關的操作之外還定義了一個事件模型 ,這個標準下的事件模型就是我們所說的2級DOM事件模型?
2級DOM的事件傳播?
?在2級DOM中,當事件發生在節點時,目標元素的事件處理函數就被觸發,而且目標的每個祖先節點也有機會處理那個事件。因為2級DOM的事件傳播分三個階段進行。第一,在capturing階段,事件從Document對象沿著文檔樹向下傳播給節點。如果目標的任何一個祖先專門注冊了事件監聽函數,那么在事件傳播的過程中就會運行這些函數。下一個階段發生在目標節點自身,直接注冊在目標上的適合的事件監聽函數將運行。第三階段是bubbling階段,這個階段事件將從目標元素向上傳播回Document對象(與capturing相反的階段)。雖然所有事件都受capturing階段的支配,但并不是所有類型的事件都bubbling。(0級DOM事件模型處理沒有capturing階段) 如:?
[xhtml]?view plaincopy
點擊a后capturing階段事件傳播會從document-> span->a,然后發生在a,最后bubbling階段事件傳播會從a->span->document 。
2級DOM的事件監聽函數注冊
2級事件模型中,可以調用對象的addEventListener()方法為元素設置事件監聽函數,也就是說通過2級DOM的這個API注冊的函數才有可能在上述事件傳播三個階段中任意一個階段捕捉到事件的發生(如果用0級DOM的2個方法賦值的事件監聽函數不能在capturing階段捕捉到事件)。
1?.addEventListener第一個參數是String,事件類型名,沒有前綴on,比如要注冊click事件就傳入“click”
,不是“onclick”
2?.第二個參數是監聽函數,在調用的時候js會傳給他一個Event對象,這個對象放了有關事件的細節,如果調用的這個對象的stopPropagation()方法,則會阻止事件傳播進一步傳播(比如在第一個階段捕捉到事件并運行事件監聽函數,其中調用了event。stopPropagation則事件就不會再被傳播經歷第二第三階段了)?
3?.第三個參數是boolean,true表示事件監聽函數能夠在三個階段中的任意一個階段捕捉到事件(符合2級DOM標準),如果是false就表示事件監聽函數不能在capturing階段捕捉到事件(表現同0級DOM)。
2級DOM中監聽函數中的this
通過addEventListener添加的函數中的this,標準中并沒有規定this必須指向目標元素, 盡管大多數瀏覽器都是這么實現的,但最終還是取決于瀏覽器的實現,我們需要用到目標元素的時候請調用event.currentTarget.?
2級DOM的Event對象?
?用addEventListener添加的事件監聽函數,在被調用的時候js會傳給他一個Event對象,下面就是這個Event對象的常用屬性
type:?
?????? 發生的事件的類型,例如"click", "mouseover"
target:?
?????? 發生事件的節點,可能與currentTarget不同
currentTarget:?
正在處理事件的節點,如果在capturing階段和冒泡階段處理事件,這個屬性就與target屬性不同。在事件監聽函數中應該用這個屬性而不是this
stopPropagation():?
可以阻止事件從當前正在處理他的節點傳播
preventDefault():?
阻止瀏覽器執行與事件相關的默認動作,與0級DOM中返回false一樣
clientX, clientY:?
鼠標相對于瀏覽器的x坐標y坐標
screenX, screenY:?
鼠標相對于顯示器左上角的x坐標y坐標
IE事件模型
1.Event對象不是傳遞給事件監聽函數,而是通過Window對象的event屬性訪問Event對象.
2.IE Event對象常用屬性
type:??????????? ? ? ? ? ??
??????? 兼容DOM的type屬性
srcElement:?
?????? 兼容DOM的target屬性
clientX, clientY:??? ? ?
?????? 兼容DOM的clientX, clientY屬性
cancelBubble:?
?????? 布爾值,設為true同調用stopPropagation()
returnValue:?
?????? 布爾值,設為false同調用preventDefault()
?????????????
3.事件監聽函數注冊
沒有addEventListener,只有attachEvent。2個參數,同addEventListener前兩個,只是事件名帶前綴on。 IE事件模型沒有capturing階段所以調用attachEvent相當于調用addEvetnListener且第三個參數為false:
相當于
4.用attachEvent注冊的函數將被作為全局函數調用,而不是作為發生事件的文檔元素的方法,也就是說this引用的是Window對象,而不是事件的目標元素。
總結
以上是生活随笔為你收集整理的javascript中0级DOM和2级DOM事件模型浅析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript中的一些细节
- 下一篇: javascript中定义事件的三种方式