- 事件捕捉(Event Capture)的實(shí)現(xiàn)問(wèn)題
- IE的高級(jí)事件處理模型的問(wèn)題
一、事件捕捉(Event Capture)的實(shí)現(xiàn)問(wèn)題
首先在說(shuō)這件事前,先感謝一下Realazy。
W3C DOM Level2的事件模型規(guī)范中,事件在DOM樹(shù)中的傳播過(guò)程(從根節(jié)點(diǎn)到目標(biāo)節(jié)點(diǎn))被分為了兩個(gè)階段:捕捉(Capture)和冒泡(Bubbling)。下面這個(gè)圖能大概的說(shuō)明整個(gè)過(guò)程:
(from W3C)
如果想創(chuàng)建一個(gè)捕捉事件,在支持W3C 事件模型的瀏覽器中,將addEventListener的第三個(gè)參數(shù)設(shè)為true就好了。例如:
document.getElementById('foo').addEventListener('click',function(){alert('Hello, world!');},true);
前一陣因?yàn)橄肱录蹲,所以做了點(diǎn)小實(shí)驗(yàn),分別在Firefox 2、Safari 3 on Windows和Opera 9上實(shí)踐了事件捕捉(當(dāng)然,因?yàn)镮E不支持事件捕捉,所以…),實(shí)驗(yàn)的原理見(jiàn)下圖:
ID為div1和div2的兩個(gè)元素都被委派了捕捉階段的事件處理函數(shù),這樣:
- 當(dāng)點(diǎn)擊#div1(藍(lán)色區(qū)域)時(shí),應(yīng)該會(huì)alert出”div1″
- 當(dāng)點(diǎn)擊#div2(黃色區(qū)域)時(shí),應(yīng)該會(huì)先alert出”div1″,再alert出”div2″,因?yàn)樵谑录蹲诫A段,事件是從根元素向下傳播的,#div1是#div2的父元素,自然綁定在#div1上的click事件也會(huì)先于#div2上的click事件被執(zhí)行。
然而,以上的設(shè)想只試用于Firefox 2和Safari 3 on Windows,在Opera 9中,事情會(huì)變成這樣:
- 當(dāng)點(diǎn)擊#div1(藍(lán)色區(qū)域)時(shí),什么都不會(huì)發(fā)生
- 當(dāng)點(diǎn)擊#div2(黃色區(qū)域)時(shí),會(huì)alert出”div1″,隨后什么都不會(huì)再發(fā)生
可以看出,在Opera 9中,目標(biāo)元素(TargetElement)的click事件沒(méi)有被執(zhí)行。通過(guò)Realazy(orz…)的指點(diǎn),找到了這篇文章:《Event capture explained》,發(fā)現(xiàn),
來(lái)Opera中的實(shí)現(xiàn)才是正確的。此文中有一段話如是說(shuō): The DOM spec states that capturing events should not fire on target, because the idea of a capturing event is to detect events before they reach their targets. Because of bugs in Gecko and Safari, web content that is tested mostly with Firefox or other Gecko-based browsers sometimes expects capturing listeners to fire on target. Such content will fail in Opera 7, 8 and current releases of 9 because of its correct implementation of the standard.
大意是說(shuō):DOM規(guī)范中陳述了捕捉型的事件不應(yīng)該在目標(biāo)元素上被執(zhí)行,因?yàn)椴蹲叫褪录挠靡饩褪菫榱吮O(jiān)測(cè)到達(dá)目標(biāo)元素之前的事件。Firefox和Safari的實(shí)現(xiàn)都是帶有bug的。
再來(lái)看看W3C的DOM Events規(guī)范中的原話: A capturing EventListener will not be triggered by events dispatched directly to the EventTarget upon which it is registered.
所以,在整個(gè)事件傳播中,被執(zhí)行的順序是:
- 父元素中所有的捕捉型事件(如果有)自上而下地執(zhí)行
- 目標(biāo)元素的冒泡型事件(如果有)
- 父元素中所有的冒泡型事件(如果有)自下而上地執(zhí)行
在了解了這些后,也許還是不要使用事件捕捉為妙,至少暫時(shí)不要。
出處:三月的蟻穴
責(zé)任編輯:tada
上一頁(yè) 下一頁(yè) IE的高級(jí)事件處理模型的問(wèn)題
◎進(jìn)入論壇網(wǎng)頁(yè)制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|