一、事件的發生順序
這個問題的起源非常簡單,假設你在一個元素中又嵌套了另一個元素
二、兩種模型
不出所料,在那些「不堪回首」(瀏覽器大戰)的日子裡,Netscape和微軟有兩種截然不同的處理方法:Netscape主張元素1的事件首先發生,這種事件發生順序被稱為捕獲型
微軟則保持元素2具有優先權,這種事件順序被稱為冒泡型
這兩種事件順序是截然相反的。 Explorer瀏覽器只支援冒泡事件,Mozilla,Opera7和Konqueror兩者都支援。而更古老的opera和iCab兩者都不支持
三、捕獲型事件
當你使用捕獲型事件時四、冒泡型事件
使用冒泡型事件W3c明智的在這場爭鬥中選擇了一個擇中的方案。任何發生在w3c事件模型的事件,首是進入捕獲階段,直到達到目標元素,再進入冒泡階段
複製程式碼
(事件在這裡就像一個觀光客,由外至內遊覽,逐漸接近被觸發的主要元素,然後又反向離開)
1.點選事件首先進入捕獲階段開始(逐漸接近元素2的方向)。查看元素2的祖先元素中是否有在捕獲階段有onclick處理函數的
2.發現元素1有一個,於是doSomething2被執行
3.事件檢查到目標自己(元素2),捕獲階段沒有發現了更多的處理函數。事件開始進入冒泡階段,想當然執行doSomething(),這個綁定於元素2冒泡階段的函數。
4.事件向遠離元素2的方向,查看是否有任何祖先元素在冒泡階段綁定了一個處理函數。沒有這樣的情況,所以什麼也沒發生
相反的情況是:
2.事件檢查到目標自己。事件開始進入冒泡階段,並執行綁定於元素2冒泡階段的函數。 doSomething()
3.事件開始遠離目標,檢查元素2的祖先元素中是否有在冒泡階段綁定了處理函數的
4.發現了一個,於是元素1的doSomething2()被執行
六、相容性與傳統模式
在支援w3c dom(文檔物件模型) 的瀏覽器中,傳統的事件綁定方法是複製程式碼
程式碼如下:element1.onclick = doSomething2;
預設被視為在綁定於冒泡階段
在頁面上點擊任何元素的點擊事件,最終會冒泡至頁面最高文檔層,因此觸發那個通用的處理函數,除非先前處理函數明確的指出終止冒泡,這樣才冒泡才不會傳播到整個文件層面
上面程式碼第二句的補充:
>>>先說IE
object.setCapture() 當一個object的被 setCapture 後,他的方法將會被繼承到整個文件進行捕獲。
當不需要把方法繼承到整個文件捕獲時,要用object.releaseCapture()
>>>others
Mozilla 也有類似的功能,方法稍微不同
window.captureEvents(Event. eventType)
window.releaseEvents(Event.eventType)
>>>example
複製程式碼
複製程式碼
代碼如下:
---------------------------- --------| document ,
| --------------- ------------ || --------------- ------------ | | element1 | | element2 | |
| --------------- ------------ |
----- -------------------------------
element1.onclick = doSomething;element2.onclick = doSomething;document.onclick = defaultFunction;
現在如果使用者點選元素1或元素2,doSomething()將會執行。如果你願意的話,如果你不想讓事件冒泡至執行defaultFunction(),你可以在這裡阻止事件冒泡向上傳播,。但如果使用者點選頁面上的其他部位,defaultFunction()還是會被執行。這樣的效果或許有時能用的上。
設定頁面-使處理函數有範圍較大的觸發面積,在「拖曳效果」腳本中是必須的。一般來說在某一個元素層上發生 mousedown事件意味著選擇了這個元素,並且使它能夠回應mousemove事件。雖然mousedown通常綁定於這個元素層上以避免瀏覽器bug,但是其他兩者的事件函數的範圍必須是整個頁面(?)
{
if (!e) var e = window.event;
e.cancelBubble = true;
}
在支援cancelBubble屬性的瀏覽器中設定cancelBubble無傷大雅。瀏覽器會聳一聳肩然後創造一個這個屬性。當然這也並不能真正的取消冒泡,但至少能保證這條指令是安全正確的
十一、currentTarget就像我們之前看到的一樣,一個事件用target或是srcElement屬性用來表示事件究竟發生在哪個目標元素上(即使用者最初點擊的元素)。在我們的例子中是元素2,因為我們點擊了它。
程式碼如下:
如果使用者點選元素2, doSomething()會被執行兩次。但是你怎麼知道哪個html元素正在回應這個事件? target/srcElement也沒有給出線索,但人們總是更傾向於元素2,因為它是引起事件的原因(因為使用者點擊的是它)。 為了解決這個問題,w3c 增加了currentTarget這個屬性,它就指向正在處理事件的元素:這只是我們需要的。很不幸的是微軟模型中並沒有相似的屬性你也可以使用”this”關鍵字。在上面的例子中,它相當於正在處理事件的html元素,就像currentTarget。
十二、微軟模型的問題
程式碼如下:
element2.attachEvent('onclick',doSomething)
你無法確切知道哪一個HTML元素正在負責處理事件,這是微軟事件綁定模型最嚴重的問題,對我來說,這也是我從不使用它的原因,即使是在開發僅供Windows下的IE的應用程式 我希望能夠盡快增加currentTarget類似的屬性——或者遵循標準? web開發者們需要這些資訊
後記: 因為沒有實戰過javascript,所以這篇文章有些地方我並不是很理解,只能硬生的翻譯出來,比如談拖曳效果的那一段,如果大家有什麼補充和疑問可以留言給我,謝謝支持啦!