1、事件捕獲和事件冒泡與事件委托三者的關(guān)系
事件冒泡和事件捕獲分別由網(wǎng)景公式和微軟公司提出铛纬,這兩個(gè)概念都是為了解決頁(yè)面中事件流(事件發(fā)生順序)的問題厌均。事件捕獲和冒泡是現(xiàn)在瀏覽器的執(zhí)行事件的不同階段,事件委托是利用冒泡階段的運(yùn)行機(jī)制來實(shí)現(xiàn)的
運(yùn)行條件:當(dāng)一個(gè)事件發(fā)生在具有父元素的元素上時(shí),現(xiàn)代瀏覽器根據(jù)事件添加時(shí)的設(shè)置來執(zhí)行(冒泡或者捕獲)
通過addEventerListener()的第三個(gè)參數(shù)來設(shè)置事件是通過捕獲階段注冊(cè)的(true),還是冒泡階段注冊(cè)的(false),默認(rèn)情況下是false擒悬。
2模她、 事件冒泡
從實(shí)際操作的元素(事件)向父元素一級(jí)一級(jí)執(zhí)行下去,直到達(dá)到<html>
有的時(shí)候父元素和子元素都定義了click事件懂牧,但是不希望點(diǎn)擊子元素的時(shí)候執(zhí)行父元素的click事件侈净,可以通過阻止冒泡(stopPropagation())在子元素上阻止冒泡。
3僧凤、事件捕獲
瀏覽器檢查元素的最外層祖先<html>畜侦,是否在捕獲階段注冊(cè)了一個(gè)click事件處理程序,如果是躯保,則運(yùn)行它旋膳。
然后,它移動(dòng)到<html>的下一個(gè)元素(點(diǎn)擊元素的父元素)途事,并執(zhí)行相同的操作验懊,然后是下一個(gè)元素(點(diǎn)擊的元
素的父元素),以此類推盯孙,直到達(dá)到實(shí)際點(diǎn)擊的元素鲁森。
4、事件捕獲和冒泡的區(qū)別
執(zhí)行順序不同
事件冒泡:事件會(huì)從最內(nèi)層的元素開始發(fā)生振惰,一直向上傳播歌溉,直到document對(duì)象。
事件捕獲:事件從最外層開始發(fā)生骑晶,直到最具體的元素痛垛。
5、事件委托使用場(chǎng)景
如果你想要在大量子元素中單擊任何一個(gè)就可以執(zhí)行一段代碼桶蛔,這個(gè)時(shí)候可以把事件監(jiān)聽器設(shè)置在父節(jié)點(diǎn)上匙头。
當(dāng)事件捕獲和事件冒泡同時(shí)存在的情況下,事件又是如何觸發(fā)的呢仔雷?
<!--部分HTML代碼-->
<div id="s1">father
<div id='s2'>children</div>
</div>
<!--部分JS代碼-->
s1.addEventListener("click",function(e){
console.log('father的捕獲事件')
},true);
s2.addEventListener("click",function(e){
console.log('children的捕獲事件')
},true);
s1.addEventListener("click",function(e){
console.log('father的冒泡事件')
},false);
s2.addEventListener("click",function(e){
console.log('children的冒泡事件')
},false);
打印結(jié)果:
father的捕獲事件
children的捕獲事件
children的冒泡事件
father的冒泡事件
結(jié)論:
對(duì)于非target節(jié)點(diǎn)蹂析,則先執(zhí)行捕獲再執(zhí)行冒泡舔示,對(duì)于target節(jié)點(diǎn)則先執(zhí)行先注冊(cè)的事件,無論冒泡還是捕獲电抚。
先執(zhí)行非target節(jié)點(diǎn)的捕獲惕稻,然后根據(jù)注冊(cè)順序執(zhí)行target節(jié)點(diǎn)的事件,然后再執(zhí)行非target節(jié)點(diǎn)的冒泡蝙叛。
addEventerListener俺祠,IE8及以下不支持,屬于DOM2級(jí)的方法借帘,可添加多個(gè)方法不被覆蓋
解綁事件蜘渣,參數(shù)和綁定相同
removeEventListener(event.type, handle, boolean);
綁定事件兼容IE8及以下
attachEvent(event.type,handle);寫事件名時(shí)要加上on前綴 ,IE特有肺然,兼容IE8及以下蔫缸,可添加多個(gè)事件處理程序,只支持冒泡階段
由于事件捕獲階段沒有可以阻止事件的函數(shù)际起,所以一般都是設(shè)置為事件冒泡
6捂龄、阻止冒泡
e.stopPropagation()
stopPropagation是事件對(duì)象(Event)的一個(gè)方法,作用是阻止目標(biāo)元素的冒泡事件加叁,但是不會(huì)阻止默認(rèn)行為倦沧。
兼容IE
e.cancelBubble = true
阻止冒泡兼容IE寫法
window.event?window.event.cancelBubble=true:e.stopPropagation();
e && e.stopPropagation ? e.stopPropagation() : window.event.cancelBubble = true;
7它匕、取消默認(rèn)事件
e.preventDefault()
preventDefault它也是事件對(duì)象的一個(gè)方法展融,作用是取消一個(gè)目標(biāo)元素的默認(rèn)行為,既然說是默認(rèn)行為豫柬,當(dāng)然只有它有默認(rèn)行為才能被取消告希,如果元素本身無默認(rèn)行為,調(diào)用當(dāng)然無效啦烧给,比如鏈接a燕偶,提交按鈕input type="submit"等,當(dāng)event對(duì)象的cancelable為false時(shí)础嫡,表示沒有默認(rèn)行為指么,這時(shí)即使有默認(rèn)行為,調(diào)用preventDefault也是不會(huì)起作用的榴鼎。
兼容IE: return false;
js的return false只會(huì)阻止默認(rèn)行為伯诬,而是用jquery的話則既可以阻止默認(rèn)行為,有防止對(duì)象冒泡巫财。
8盗似、總結(jié)使用方法 :
停止冒泡
function stopBubble(e){
<!--如果提供了事件對(duì)象,則這是個(gè)非IE瀏覽器-->
if(e&&e.stopPropagation){
e.stopPropagation();
}else{
<!--我們需要使用IE的方式來取消事件冒泡-->
window.event.cancelBubble = true;
}
}
阻止默認(rèn)行為
function stopDefault(e){
<!--阻止默認(rèn)行為W3C-->
if(e&&e.preventDefault()){
e.preventDefault();
}else{
<!--IE中阻止默認(rèn)行為-->
return false;
}
}
}
9平项、事件注意點(diǎn):
1赫舒、event代表事件的狀態(tài)悍及,例如觸發(fā)event對(duì)象的元素,鼠標(biāo)的位置及狀態(tài)接癌、按下的鍵等并鸵。
2、event對(duì)象只在事件發(fā)生的過程中才有效
firefox里的event和IE中的不同扔涧,IE里的是全局變量,隨時(shí)可用届谈,firefox里的要用參數(shù)引導(dǎo)才能用枯夜,是運(yùn)行時(shí)的臨時(shí)變量。
在IE/Opera中是window.event艰山,在Firefox中是event;而事件的對(duì)象湖雹,在IE中是window.event.srcElement,在Firefox中是event.target曙搬,Opera中兩者都可用摔吏。