在Javascript中用戶交互的核心部分就是事件處理。本文爲對事件模型和處理機制的整體性描述。 javascript
event是用戶操做網頁時發生的交互動做,好比click/move, event除了用戶觸發的動做外,還能夠是文檔加載,窗口滾動和大小調整。 html
Event模型指的是瀏覽器如何處理髮生的事件。不一樣的瀏覽器其處理機制也不盡相同,甚至截然相反。 java
通常而言,某個界面元素髮生單個事件,那麼事件的處理對象就是該界面元素。 瀏覽器
但一個典型的問題是若是該界面元素存在父子元素,並且父子元素也定義了一樣的事件, 函數
這個時候事件該如何處理呢,事件在父子元素之間是如何傳遞的呢,誰會先接收到這個事件,又是誰先處理呢? ui
舉個例子: spa
-----------------------------------
| element1 |
| ------------------------- |
| |element2 | |
| ------------------------- |
| |
-----------------------------------
element2是element1的子元素,二者都定義了onclick事件。 code
這就是事件模型(事件序列)要解決的問題。 htm
回到網景和微軟鬥爭的年代,兩個公司選擇了不一樣的道路: 對象
網景選擇的是事件捕獲(event capturing)模型,即網景認爲element1首先獲取到事件;
微軟選擇了和其桌面系統相似的消息機制,認爲element2有更高的優先權,即事件冒泡(event bubbling),
這兩個模型截然相反,IE僅支持event bubbling. Mozilla, Opera 7等兩種都支持. 更老版本的Opera和iCab兩種都不支持。
你如今也許體會到了什麼是互聯網最初那最好也最壞的年代。
| |
--------------- | |-----------------
| element1 | | |
| ----------- | |----------- |
| |element2 \ / | |
| ------------------------- |
| Event CAPTURING |
-----------------------------------
看上面箭頭的方向,element1的事件處理器首先被觸發,而後向下傳遞到element2
/ \
--------------| |-----------------
| element1 | | |
| ----------- | |----------- |
| |element2 | | | |
| ------------------------- |
| Event BUBBLING |
-----------------------------------
與事件捕獲相反,element2的事件處理器會首先被觸發。
W3C很是理智的處理了這種差別,在二者之間採起了中和的方法,W3C模型規定任何事件首先會被捕獲直到遇到目標元素,而後再向上返回。
| | / \
-----------------| |--| |-----------------
| element1 | | | | |
| ---------------| |--| |----------- |
| |element2 \ / | | | |
| -------------------------------- |
| W3C event model |
------------------------------------------
WEB開發人員能夠經過addEventListener()方法來選擇在哪一個階段註冊事件處理器(捕獲階段仍是冒泡階段),這個方法在Advanced models中有詳細描述,其最後一個參數爲true,則表明事件在捕獲階段被處理,false則表明事件在冒泡階段被處理。
好比:
element1.addEventListener('click',doSomething2,true)
element2.addEventListener('click',doSomething,false)
事件首先被element1捕獲,而後執行doSomething2,接着事件傳遞給element2,doSomething被執行,接着,事件冒泡回溯,檢查是否有父元素(element1)定義了冒泡階段的事件處理器,這裏沒有,因此事件終止。
在支持W3C DOM的瀏覽器中,傳統的事件註冊被看做是註冊於冒泡階段。
element1.onclick = doSomething2;
1、cancelBubble(HTML DOM Event 對象屬性) :若是事件句柄想阻止事件傳播到包容對象,必須把該屬性設爲 true。
2、stopPropagation(HTML DOM Event 對象方法):終止事件在傳播過程的捕獲、目標處理或起泡階段進一步傳播。調用該方法後,該節點上處理該事件的處理程序將被調用,事件再也不被分派到其餘節點。
3、 preventDefault(HTML DOM Event 對象方法)通知瀏覽器不要執行與事件關聯的默認動做。
例子:
function stopBubble(e)
{
if (e && e.stopPropagation)
e.stopPropagation()
else
window.event.cancelBubble=true
}
把這個stopBubble(e)函數放到你想要的阻止事件冒泡函數裏面就能夠阻止事件冒泡了