冒泡型事件的基本思想是:事件按照從最特定的事件目標(biāo)到最不特定的事件目標(biāo)(document對(duì)象)的順序觸發(fā)。
<html>
<head>
<title></title>
</head>
<body onclick="theClick()">
<div onclick="theClick()">點(diǎn)擊</div>
</body>
</html>
IE5.5冒泡順序如下:
(1)<div>
(2)<body>
(3)<document>
為什么稱作冒泡疫赎、因?yàn)槭录凑誅OM的層次結(jié)構(gòu)像水泡一樣不斷上升盛撑。讓我想起了一首歌:"吹泡泡、吹泡泡捧搞、泡泡飛啊飛得高抵卫、飛到天空中、問(wèn)聲太陽(yáng)好"胎撇。
IE6呢介粘、稍微修改了冒泡型事件、這樣<html>元素也可以接收冒泡的事件创坞、還是上面的代碼碗短。
IE6的冒泡順序如下:
(1)<div>
(2)<body>
(3)<html>
(4)<document>
Mozilla1.0及更高版本也支持冒泡事件但到達(dá)了另一層次。類似IE6.0题涨,它也支持<html>元素級(jí)別的事件偎谁、不過(guò),事件"起泡"一直上升到Windows窗口對(duì)象纲堵。繼續(xù)前面的代碼巡雨、點(diǎn)擊<div>元素將造成下圖所示的事件冒泡:
捕獲型事件:
IE使用冒泡型事件、相對(duì)的席函、Netscape使用了另一種稱為捕獲型事件(eventcapturing)的解決方案铐望、事件的捕獲和冒泡剛好相反的兩種過(guò)程——捕獲型事件中、事件從最不精確的對(duì)象(document對(duì)象)開始觸發(fā)茂附、然后到最精確(也可以在窗口級(jí)別捕獲事件正蛙,不過(guò)必尋由開發(fā)人員特別指定)。Netscape不會(huì)將頁(yè)面上的很多元素暴露給事件营曼。繼續(xù)使用前面的代碼示例乒验、事件按照下面的路徑傳播:
(1)document
(2)<div>
有些人也稱之為自頂向下的事件模型,因?yàn)樗菑腄OM層次的頂端開始向下延伸的:
DOM事件流:
DOM(文檔對(duì)象模型)結(jié)構(gòu)是一個(gè)樹型結(jié)構(gòu)蒂阱,當(dāng)一個(gè)HTML元素產(chǎn)生一個(gè)事件時(shí)锻全,該事件會(huì)在元素結(jié)點(diǎn)與根節(jié)點(diǎn)之間按特定的順序傳播狂塘,路徑所經(jīng)過(guò)的節(jié)點(diǎn)都會(huì)收到該事件,這個(gè)傳播過(guò)程可稱為DOM事件流鳄厌。事件順序有兩種類型:事件捕捉和事件冒泡荞胡。
DOM標(biāo)準(zhǔn)的事件模型
我們已經(jīng)對(duì)上面兩個(gè)不同的事件模型進(jìn)行了解釋和對(duì)比。DOM標(biāo)準(zhǔn)同時(shí)支持兩種事件模型了嚎,即捕獲型事件與冒泡型事件泪漂,但是,捕獲型事件先發(fā)生新思。兩種事件流都會(huì)觸發(fā)DOM中的所有對(duì)象窖梁,從document對(duì)象開始赘风,也在document對(duì)象結(jié)束(大部分兼容標(biāo)準(zhǔn)的瀏覽器會(huì)繼續(xù)將事件是捕捉/冒泡延續(xù)到window對(duì)象)夹囚。繼續(xù)使用前面的例子、在與DOM兼容的瀏覽器中點(diǎn)擊<div>元素時(shí)邀窃、事件流的進(jìn)行如下圖:
注意因?yàn)槭录哪繕?biāo)(<div>元素)是最精確的元素(于是荸哟,在DOM樹中最深),實(shí)際上它會(huì)接收兩次事件瞬捕,一次在捕獲過(guò)程中鞍历,另一次在冒泡過(guò)程中。DOM事件模型的最獨(dú)特的性質(zhì)是肪虎,文本節(jié)點(diǎn)也觸發(fā)事件(在IE不會(huì))劣砍。所以如果點(diǎn)擊示例中的<div>點(diǎn)擊</div>、實(shí)際的事件流應(yīng)該是:
下面是一個(gè)簡(jiǎn)單的例子扇救,用于檢查瀏覽器先捕獲刑枝,再冒泡:
<!doctype html>
<meta charset=utf-8>
<div id="parent">
<div id="child"></div>
</div>
<script>
var parent = document.getElementById('parent');
var child = document.getElementById('child');
var order = [];
parent.addEventListener('click', function(){ order.push(1) }, true);
child.addEventListener('click', function(){ order.push(2) }, false);
parent.addEventListener('click', function(){ order.push(3) }, false);
child.click();
document.write(order); //[1,2,3]
</script>
第一個(gè)click為true,表示使用捕獲型事件迅腔,先執(zhí)行装畅。
第二個(gè)click為false,表示使用冒泡型事件沧烈,從最里面開始掠兄。
W3C模型是將兩者進(jìn)行中和,在W3C模型中锌雀,任何事件發(fā)生時(shí)蚂夕,先從頂層開始進(jìn)行事件捕獲,直到事件觸發(fā)到達(dá)了事件源元素再開始冒泡腋逆。
前端開發(fā)工作中婿牍,由于瀏覽器兼容性等問(wèn)題,我們會(huì)經(jīng)常用到“停止事件冒泡”和“阻止瀏覽器默認(rèn)行為”闲礼。
1.阻止瀏覽器的默認(rèn)行為
function stopDefault(e) {
//如果提供了事件對(duì)象牍汹,則這是一個(gè)非IE瀏覽器
if(e && e.preventDefault) {
//阻止默認(rèn)瀏覽器動(dòng)作(W3C)
e.preventDefault();
} else {
//IE中阻止函數(shù)器默認(rèn)動(dòng)作的方式
window.event.returnValue = false;
}
return false;
}
2.停止事件冒泡
function stopBubble(e) {
//如果提供了事件對(duì)象铐维,則這是一個(gè)非IE瀏覽器
if(e && e.stopPropagation) {
//因此它支持W3C的stopPropagation()方法
e.stopPropagation();
} else {
//否則,我們需要使用IE的方式來(lái)取消事件冒泡
window.event.cancelBubble = true;
}
return false;
}
jquery的寫法:
1)return false :In event handler ,prevents default behavior and event bubbing 慎菲。
return false 在事件的處理中嫁蛇,可以阻止默認(rèn)事件和冒泡事件。
2)event.preventDefault():In event handler ,prevent default event (allows bubbling) 露该。
event.preventDefault()在事件的處理中睬棚,可以阻止默認(rèn)事件但是允許冒泡事件的發(fā)生。
3)event.stopPropagation():In event handler ,prevent bubbling (allows default behavior).
event.stopPropagation()在事件的處理中解幼,可以阻止冒泡但是允許默認(rèn)事件的發(fā)生
prototype的寫法:
Event.stop(event)
學(xué)習(xí)交流抑党,請(qǐng)加群:654979292