深入理解javascript事件處理函數綁定三部曲(三)——高級事件函數綁定模型

【轉載】深入理解javascript事件處理函數綁定三部曲(三)——高級事件函數綁定模型

在這一篇中我將解釋兩種更高級的事件綁定模型:W3C和微軟。又因爲沒有一種真正跨瀏覽器的,所以,至少現在,並不贊成使用它們。

 

W3C和微軟都開發了它們自己的事件綁定模型,用來取代Netscape的傳統模型。我對微軟的模型頗爲不爽,但是W3C的除了一點小瑕疵外還是不錯的,可不幸的是很少的瀏覽器支持它。

 

w3c

w3c的DOM level2對傳統模型中出現的問題都給予了特別的注意。它提供了一種簡單的綁定方式,你可以在同一個元素上綁定隨意數量的處理函數

 

w3c事件綁定模型的關鍵在於它的addEventListener()方法。你需要傳入三個參數:事件類型,需要執行的函數,和一個布爾值(true or false),我隨後會解釋關於這個布爾值的含義。比如說給onclick綁定我們熟悉的不能在熟悉的doSomething()函數,你可以這麼做:

element.addEventListener('click',doSomething,false)

 

這個模型的美妙之處,在於我們可以許許多多事件監聽(event listener)給想要的元素,如果我們把上一篇的例子拿來使用,應該這樣寫:

element.addEventListener('click',startDragDrop,false)

element.addEventListener('click',spyOnUser,false)

 

當用戶點擊元素時兩個處理函數都會被觸發。請注意W3C模型並沒有註明哪一個處理函數會首先被觸發,所以你不能直接假設startDragDrop()會先於spyOnUser()執行。

 

如果想要移除處理函數,則要使用removeEventListener()方法。你可以選擇移除哪一個處理函數,如:

element.removeEventListener('click',spyOnUser,false)

 

刪除第二個函數但是留下第一個。太棒了,它正好解決了在傳統模型中我們遇到的麻煩。

 

匿名函數

你也可以在W3C模型中使用匿名函數

element.addEventListener('click',function () {

         this.style.backgroundColor = '#cc0000'

},false)

 

true or false

true 或者是false是addEventListener最後一個參數,它意味着處理函數是在捕獲階段還是冒泡階段執行。如果你不確定的話,使用false吧(冒泡)

 

this

在javascript中,this關鍵字是對某個函數“擁有者”的引用。在事件處理函數中它非常的有用,是對正在處理事件的html元素的引用,以至於你可以很輕鬆的對他進行訪問。

 

不幸的是儘管this關鍵字非常強大,但如果你不是非常清楚它的工作原理的話,它也非常難使用。我在另一篇文章中有討論

 

在W3C模型中,它和傳統模型中工作原理是相同的,是對正在處理事件的html元素的引用。

複製代碼
element.addEventListener('click',doSomething,false);

another_element.addEventListener('click',doSomething,false);

function doSomething() {

         this.style.backgroundColor = '#cc0000';

}
複製代碼

 

如果給任意一個html元素的click事件綁定了一個doSomething()函數,則當用戶點擊它時它會變成紅色背景

 

哪一個函數被綁定?

W3C綁定模型的問題之一就是你沒辦法找出已經給某個元素綁定的處理函數。在傳統模型中你可以這麼做:

alert(element.onclick)

 

你可以看到綁定給它的函數,如果提示是undefined的話表示什麼都沒有註冊。在最近的DOM Level 3 Events中W3C新增了eventListenerList來存儲現階段被綁定的函數。這個功能還沒有被所有的瀏覽器支持,它太新了(譯者注:就當是情況而已)。無論如何,這個問題還是被解決了。

幸運的是,如果你想移除一個並沒有綁定的函數,removeEventListener()並不會給出錯誤提示,所以你可以肆無忌憚的使用removeEventListener()

微軟

微軟同樣開發了一套自己的綁定模型。看上去和W3C 的很像,但是有一些嚴重的缺陷。

想要綁定一個處理函數:把它attach給一個元素:

element.attachEvent('onclick',doSomething)

 

或者你需要兩個處理函數:

element.attachEvent('onclick',startDragDrop)

element.attachEvent('onclick',spyOnUser)

 

移除一個也很簡單:

element.detachEvent('onclick',spyOnUser)

 

缺陷

如果和W3C模型比較,微軟模型有兩個嚴重的缺陷:

  1. 事件總是冒泡的,沒有捕獲的可能性
  2. 處理函數總是被引用,而非複製。所以其中的this關鍵字總是指向window,一點用都沒有。

這兩個弱點會導致當一個事件冒泡時,是不可能知道哪一個html元素正在處理事件,我會在另一篇文章中詳細解釋

 

因爲微軟模型只在IE5或者更高版本中支持,所以它不能誇瀏覽器。但是即使是在IE中,也最好別使用它,因爲冒泡問題在一些複雜的應用中會變得相當棘手

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章