文章目錄
- 匿名函數
- true或者false
- this
- 哪個事件處理常式被註冊了呢?
- 缺陷
在這一章我會講解兩種進階時間註冊模型:W3C和微軟的。因為這兩個方法都不能跨瀏覽器,所以在現在看來他們的使用場合并不多。
W3C和微軟都著力於發展自己的事件註冊模型來取代Netscape的傳統模型。雖然對於微軟的模型我不是很感冒,但是w3c的還是不錯的,除了這個滑鼠定位 的問題。不過現在只有小部分瀏覽器支援。
W3C
W3C的DOM層面事件規範注意到了傳統模式的問題。他對於你想在一個元素上綁定多個事件提供了一個很好的解決辦法。
W3C事件註冊模型的關鍵就是addEventListener()。你給他三個參數:事件類型,要執行的函數和一個布爾值(true或者false)我一會再解釋。把我們熟知的doSomething()函數註冊到一個元素的onclick事件上,你可以這樣做:
element.addEventListener('click',doSomething,false)
這種模型的魅力在於我們可以想加多少監聽就可以加多少。如果用我們之前的傳統模式裡面的例子,我們就可以寫成這樣:
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或者false
true或者false是addEventListener的最後一個參數,意思是你想讓你的函數在捕獲階段還是冒泡階段執行。如果你不確定,那就使用false(冒泡階段)。
this
在JavaScript裡this關鍵字通常指函數的所有者。如果this指向事件發生的HTML元素,那麼一切都是那麼的美好,你可以很簡單的做很多事情。
不幸的是,雖然this非常的強大,但是如果你不是明確的知道他怎麼運作的話使用起來還是比較難的。關於這個我在另一個地方有詳細的討論。
在w3c模型下他的運作和在傳統模式下是一樣的:他表示現在正在處理事件的HTML元素。
element.addEventListener('click',doSomething,false);another_element.addEventListener('click',doSomething,false);function doSomething() { this.style.backgroundColor = '#cc0000';}
如果你把doSomething()註冊在任意一個HTML元素的click實踐上,那麼當使用者點擊的時候這個元素的背景就會變成紅色。
哪個事件處理常式被註冊了呢?
現在這個W3C事件註冊模式有一個問題就是你不知道一個元素都有哪些事件處理常式被註冊了。在傳統模式下面你可以:
alert(element.onclick)
你就可以看到哪些函數註冊了,undefined就是沒有函數註冊在這個事件上。只是在最近的DOM Level 3事件中W3C才添加了一個eventListenerList來儲存已經註冊了的事件處理常式。因為太新了,鮮有瀏覽器支援。然而,問題已經解決了。
還好的是removeEventListener()不會因為你沒有註冊元素的某個事件而返回錯誤,所以你可以不用擔心的使用removeEventLister()。
微軟
微軟也有一個事件註冊模型。跟W3C的很像,但是有一個嚴重的缺陷。
註冊一個事件處理常式,attach到一個元素:
element.attachEvent('onclick',doSomething)
或者,你需要兩個事件處理常式:
element.attachEvent('onclick',startDragDrop)element.attachEvent('onclick',spyOnUser)
移除一個也非常簡單:
element.detachEvent('onclick',spyOnUser)
缺陷
跟W3C的相比較,微軟有兩個嚴重的問題:
1、事件總是冒泡,沒有被捕捉的可能。
2、事件處理常式是被引用的,而不是拷貝的,所以this關鍵字總是指向window然後就一點用都沒有。
這兩個問題的結果就是如果一個事件冒泡了那麼你是沒有可能知道哪個元素在處理事件。在後面的事件順序一章我會詳細的解釋。
而且微軟的標準只被IE支援,也不能用來跨瀏覽器。就算你只是給windows瀏覽器寫指令碼也最好別用,因為冒泡問題會讓事情變得不可收拾。
繼續
如果你想繼續學習,請看下一章。
原文地址:http://www.quirksmode.org/js/events_advanced.html
第一次翻譯 大家多多包含 我的twitter:@rehawk