JavaScript中事件冒泡與事件捕獲

2021-06-20 04:52:50 字數 2740 閱讀 3742

如圖:現在有3個巢狀div,且都有onclick事件,當div_3被單擊時,依次觸發div_3=>div_2=>div_1的click事件。 

這就是事件冒泡:當乙個事件被觸發時,依次由最上層元素(div_3)向下遍歷並執行該元素及父元素相同事件的過程就是事件冒泡。

當事件由最底層(div_1)向上遍歷並執行時稱為事件捕獲。

如圖,冒泡事件之所存在與js的事件處理機制有關,事件的觸發過程是這樣:

i:某元素事件被觸發,會找到其父元素及祖父元素直至根元素,並組成「樹」

ii:從「樹」根元素向上尋找父元素,若父元素包含有該事件且註冊事件的usercapture引數為true(這個屬性下文會講到)便觸發

iii:繼續向上遍歷尋找父元素的父元素,並進行相同的判斷,直至正真觸發事件的「頂層」元素(到此為止的過程便是事件捕獲過程)

iiii:到達「頂部」之後,再往下從「葉子」往「根」再次遍歷(事件冒泡開始),若元素包含有該事件且註冊事件的usercapture引數為false便觸發

v:不斷遍歷,到根部結束(事件冒泡結束)

這就產生了事件冒泡與事件捕獲的概念。

先看**,我們加了3個div(執行結果與上文第一幅圖相同):

div_1 

div_2

div_3

click me!

現在:單擊div_3看看會怎樣?

結果:依次彈出「div_1」=>「div_2」=>"div_3"

我們注意到這裡用了乙個函式addeventlistener();他的作用是為元素註冊事件,你可以將它理解為與οnclick=「***()」 類似,但是任有區別(區別參考這裡)

他有3個引數,分別是:eventtype:表示事件型別

function:觸發事件將執行的函式

usercapture:是否執行捕捉

前兩個引數從字面就可以理解,但是第三個引數值什麼意思?

所謂執行捕捉,是指在事件捕獲的過程中需要觸發的事件,若該引數為false則只會觸發事件冒泡,若為true,則只會觸發事件捕獲。

為了驗證,我們修改上面的init()函式,如下:

function init(),false);

document.getelementbyid("div_2").addeventlistener("click",function (),true);

document.getelementbyid("div_3").addeventlistener("click",function (),false);

}

將div_1與div_3的usercapture引數改為false。這樣,按照我們上面的定義,這次單擊div_3彈框順序應該是:div_2=>div_3=>div_1.

經測試,確實如此  :)

通過實驗,我們已經對js事件機制有了更深層次理解:

事件冒泡更準確的說是,乙個元素事件被觸發時遍歷執行其「元素樹」上所有非捕捉(usercapture=false)同類事件的過程。

事件捕獲更準確的說是,乙個元素事件被觸發時遍歷執行其「元素樹」上所有捕捉(usercapture=false)同類事件的過程。

優點

因為這些特性,他有一些好處供我們利用:如,在頁面上有乙個大的div,在裡面散布裡大量元素,我只需給這個div加上click事件就能獲知是誰觸發了click,而不用每個元素都註冊事件。

我們做個示例,修改了上面的html,只給div_1添註冊了事件,getaimele()獲取當前事件源:

div_1 

div_2

div_3

click me!

這時候,單擊div_3,會彈出"div_3",而我們並沒有特意為他註冊事件。

缺點

缺點也是顯而易見的,當我不需要觸發事件時執行父類相同事件方法的時候,冒泡就成了極大的缺陷,他會執行不該執行的**,讓執行速度減慢,而且導致的bug也不容易發現。

例如,如果你使用了mouseover一類會頻繁觸發的事件,每次滑鼠的移動會導致一次「元素樹」的遍歷,那效能會是很大問題

正確使用冒泡非常重要,當需要「冒泡」的時候讓他「冒」,不需要的時候,則應該及時阻止。

阻止有兩種方式:cancelbubble=true(ie中使用,),stoppropagation()(ff及谷歌中使用)。注意:ie高版本實際上兩者都開始支援

這時候,我們修改html,3個div都註冊了單擊事件,但是div_2處用了「阻止冒泡」:

div_1 

div_2

div_3

click me!

單擊div_3,效果是:div_3=>div_2

由於div_2執行之後阻止了冒泡,div_1沒有被執行

對於「捕獲事件」(usercapture=true),上面的方法依然適用。

就是說,這種阻止冒泡方式實際上是限制了js的事件機制,所以中斷了「元素樹」的遍歷。

Javascript中的事件繫結

等價於 window.nl ad bodyonload 如果希望乙個事件繫結多個方法,這樣是不行的 window.nl ad bodyonload1 window.nl ad bodyonload2 window.nl ad bodyonload3 他只會執行最後乙個,這裡有個dom方法 attac...

Javascript中事件處理程式

事件繫結 事件處理程式 var fun function 移除事件處理程式 fun function 優點 簡單方便 缺點 js和html耦合度太高,每次修改函式要變動兩個地方。存在乙個時差問題,使用者可能會在html元素一出現就觸發事件,但是事件處理程式沒有載入好document.geteleme...

javascript中事件流機制

1.js中事件流機制,分為三個階段,事件捕獲階段 處於目標階段 事件冒泡階段 2.事件捕獲階段,瀏覽器會從根節點開始由外到內進行事件傳播 事件傳播的順序是 window document div div 結點 通過函式新增 element.addeventlistener event,functio...