Javascript事件模型:事件捕獲和事件冒泡

Javascript中用戶交互的核心部分就是事件處理。本文爲對事件模型和處理機制的整體性描述。 javascript

Event是什麼?

event是用戶操做網頁時發生的交互動做,好比click/move, event除了用戶觸發的動做外,還能夠是文檔加載,窗口滾動和大小調整。 html

 

Event模型是什麼?

Event模型指的是瀏覽器如何處理髮生的事件。不一樣的瀏覽器其處理機制也不盡相同,甚至截然相反。 java

通常而言,某個界面元素髮生單個事件,那麼事件的處理對象就是該界面元素。 瀏覽器

但一個典型的問題是若是該界面元素存在父子元素,並且父子元素也定義了一樣的事件, 函數

這個時候事件該如何處理呢,事件在父子元素之間是如何傳遞的呢,誰會先接收到這個事件,又是誰先處理呢? ui

舉個例子: spa

----------------------------------- 

| element1 | 

| ------------------------- | 

| |element2 | | 

| ------------------------- | 

| | 

----------------------------------- 

element2element1的子元素,二者都定義了onclick事件。 code

這就是事件模型(事件序列)要解決的問題。 htm

 

兩種模型

回到網景和微軟鬥爭的年代,兩個公司選擇了不一樣的道路: 對象

網景選擇的是事件捕獲(event capturing)模型,即網景認爲element1首先獲取到事件;

微軟選擇了和其桌面系統相似的消息機制,認爲element2有更高的優先權,即事件冒泡(event bubbling)

這兩個模型截然相反,IE僅支持event bubbling. Mozilla, Opera 7等兩種都支持. 更老版本的OperaiCab兩種都不支持。

你如今也許體會到了什麼是互聯網最初那最好也最壞的年代。

 

事件捕獲

     | | 

--------------- | |----------------- 

| element1   | | | 

| -----------    | |----------- | 

| |element2  \ / | | 

| ------------------------- | 

| Event CAPTURING | 

----------------------------------- 

看上面箭頭的方向,element1的事件處理器首先被觸發,而後向下傳遞到element2

事件冒泡

 / \ 

--------------| |----------------- 

| element1 | | | 

| ----------- | |----------- | 

| |element2 | | | | 

| ------------------------- | 

| Event BUBBLING | 

----------------------------------- 

與事件捕獲相反,element2的事件處理器會首先被觸發。

 

W3C模型

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,接着事件傳遞給element2doSomething被執行,接着,事件冒泡回溯,檢查是否有父元素(element1)定義了冒泡階段的事件處理器,這裏沒有,因此事件終止。

 

兼容傳統模型

在支持W3C DOM的瀏覽器中,傳統的事件註冊被看做是註冊於冒泡階段。

element1.onclick = doSomething2; 

 

javascript 的事件冒泡如何阻止

 

1cancelBubbleHTML DOM Event 對象屬性) :若是事件句柄想阻止事件傳播到包容對象,必須把該屬性設爲 true 

 

2stopPropagationHTML DOM Event 對象方法):終止事件在傳播過程的捕獲、目標處理或起泡階段進一步傳播。調用該方法後,該節點上處理該事件的處理程序將被調用,事件再也不被分派到其餘節點。 

 

3 preventDefaultHTML DOM Event 對象方法)通知瀏覽器不要執行與事件關聯的默認動做。 

 

例子: 

 function stopBubble(e) 

 { 

 if (e && e.stopPropagation) 

 e.stopPropagation() 

 else 

 window.event.cancelBubble=true 

 } 

 

把這個stopBubble(e)函數放到你想要的阻止事件冒泡函數裏面就能夠阻止事件冒泡了
相關文章
相關標籤/搜索