一:什么是事件流呢?
通俗的來說轴咱,可以想象畫在一張紙上的一組同心圓汛蝙。如果你把手指放在圓心上烈涮,那么你的手指指向的不是一個(gè)圓,而是紙上的所有圓窖剑。兩家公司的瀏覽器開發(fā)團(tuán)隊(duì)在看待瀏覽器事件方面還是一致的坚洽。如果你單擊了某個(gè)按鈕,他們都認(rèn)為單擊事件不僅僅發(fā)生在按鈕上西土。換句話說讶舰,在單擊按鈕的同時(shí),你也單擊了按鈕的容器元素需了,甚至也單擊了整個(gè)頁面跳昼。
事件流描述的是從頁面中接收事件的順序。但有意思的是肋乍,IE 和Netscape 開發(fā)團(tuán)隊(duì)居然提出了差不多是完全相反的事件流的概念鹅颊。IE 的事件流是事件冒泡流,而Netscape Communicator 的事件流是事件捕獲流墓造。
二:事件冒泡
IE 的事件流叫做事件冒泡(event bubbling)堪伍,即事件開始時(shí)由最具體的元素(文檔中嵌套層次最深的那個(gè)節(jié)點(diǎn))接收,然后逐級向上傳播到較為不具體的節(jié)點(diǎn)(文檔)觅闽。
以下面的HTML 頁面為例:
如果你單擊了頁面中的btn元素杠娱,那么這個(gè)click 事件會按照如下順序傳播:
1:div
2:body
3:html
4:document
也就是說,click 事件首先在div元素上發(fā)生谱煤,而這個(gè)元素就是我們單擊的元素摊求。然后,click事件沿DOM樹向上傳播刘离,在每一級節(jié)點(diǎn)上都會發(fā)生室叉,直至傳播到document 對象。如圖 展示了事件冒泡的過程硫惕。
所有現(xiàn)代瀏覽器都支持事件冒泡茧痕,但在具體實(shí)現(xiàn)上還是有一些差別。IE5.5 及更早版本中的事件冒泡會跳過元素(從直接跳到document)。IE9璃谨、Firefox贩挣、Chrome 和Safari 則將事件一直冒泡到window 對象。
三:事件捕獲
Netscape Communicator 團(tuán)隊(duì)提出的另一種事件流叫做事件捕獲(event capturing)令野。事件捕獲的思想是不太具體的節(jié)點(diǎn)應(yīng)該更早接收到事件,而最具體的節(jié)點(diǎn)應(yīng)該最后接收到事件徽级。事件捕獲的用意在于在事件到達(dá)預(yù)定目標(biāo)之前捕獲它气破。如果仍以前面的HTML 頁面作為演示事件捕獲的例子,那么單擊元素就會以下列順序觸發(fā)click 事件餐抢。
如果你單擊了頁面中的div元素现使,那么這個(gè)click 事件會按照如下順序傳播:
1:document
2:html
3:body
4:div
在事件捕獲過程中低匙,document 對象首先接收到click 事件,然后事件沿DOM 樹依次向下碳锈,一直傳播到事件的實(shí)際目標(biāo)顽冶,即元素。如圖展示了事件捕獲的過程售碳。
雖然事件捕獲是Netscape Communicator 唯一支持的事件流模型渗稍,但I(xiàn)E9、Safari团滥、Chrome竿屹、Opera和Firefox 目前也都支持這種事件流模型。盡管“DOM2 級事件”規(guī)范要求事件應(yīng)該從document 對象開始傳播灸姊,但這些瀏覽器都是從window 對象開始捕獲事件的拱燃。由于老版本的瀏覽器不支持,因此很少有人使用事件捕獲力惯。我們也建議讀者放心地使用事件冒泡碗誉,在有特殊需要時(shí)再使用事件捕獲。
四:DOM事件流
“DOM2級事件”規(guī)定的事件流包括三個(gè)階段:事件捕獲階段父晶、處于目標(biāo)階段和事件冒泡階段哮缺。首先發(fā)生的是事件捕獲,為截獲事件提供了機(jī)會甲喝。然后是實(shí)際的目標(biāo)接收到事件尝苇。最后一個(gè)階段是冒泡階段,可以在這個(gè)階段對事件做出響應(yīng)埠胖。以前面簡單的HTML 頁面為例糠溜,單擊元素會按照如圖所示順序觸發(fā)事件。
在DOM 事件流中直撤,實(shí)際的目標(biāo)(元素)在捕獲階段不會接收到事件非竿。這意味著在捕獲階段,事件從document 到再到后就停止了谋竖。
多數(shù)支持DOM 事件流的瀏覽器都實(shí)現(xiàn)了一種特定的行為红柱;即使“DOM2 級事件”規(guī)范明確要求捕獲階段不會涉及事件目標(biāo),但I(xiàn)E9蓖乘、Safari锤悄、Chrome、Firefox 和Opera 9.5 及更高版本都會在捕獲階段觸發(fā)事件對象上的事件驱敲。結(jié)果铁蹈,就是有兩個(gè)機(jī)會在目標(biāo)對象上面操作事件宽闲。
IE9众眨、Opera握牧、Firefox、Chrome 和Safari 都支持DOM 事件流娩梨;IE8 及更早版本不支持DOM 事件流沿腰。
來源于:JavaScript高級程序設(shè)計(jì)第三版