如圖:現在有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...