javascript事件冒泡和事件捕獲詳解
事件冒泡和事件捕獲分別由微軟和網(wǎng)景公司提出,這兩個(gè)概念都是為了解決頁面中事件流(事件發(fā)生順序)的問題。
<div id="outer"> <p id="inner">Click me!</p> </div>
上面的代碼當(dāng)中一個(gè)div元素當(dāng)中有一個(gè)p子元素,如果兩個(gè)元素都有一個(gè)click的處理函數(shù),那么我們?cè)趺床拍苤滥囊粋€(gè)函數(shù)會(huì)首先被觸發(fā)呢?
為了解決這個(gè)問題微軟和網(wǎng)景提出了兩種幾乎完全相反的概念。
事件冒泡
微軟提出了名為事件冒泡(event bubbling)的事件流。事件冒泡可以形象地比喻為把一顆石頭投入水中,泡泡會(huì)一直從水底冒出水面。也就是說,事件會(huì)從最內(nèi)層的元素開始發(fā)生,一直向上傳播,直到document對(duì)象。
因此上面的例子在事件冒泡的概念下發(fā)生click事件的順序應(yīng)該是p -> div -> body -> html -> document
事件捕獲
網(wǎng)景提出另一種事件流名為事件捕獲(event capturing)。與事件冒泡相反,事件會(huì)從最外層開始發(fā)生,直到最具體的元素。
上面的例子在事件捕獲的概念下發(fā)生click事件的順序應(yīng)該是document -> html -> body -> div -> p
addEventListener的第三個(gè)參數(shù)
“DOM2級(jí)事件”中規(guī)定的事件流同時(shí)支持了事件捕獲階段和事件冒泡階段,而作為開發(fā)者,我們可以選擇事件處理函數(shù)在哪一個(gè)階段被調(diào)用。
addEventListener方法用來為一個(gè)特定的元素綁定一個(gè)事件處理函數(shù),是JavaScript中的常用方法。addEventListener有三個(gè)參數(shù):
element.addEventListener(event, function, useCapture)
第一個(gè)參數(shù)是需要綁定的事件,第二個(gè)參數(shù)是觸發(fā)事件后要執(zhí)行的函數(shù)。而第三個(gè)參數(shù)默認(rèn)值是false,表示在事件冒泡的階段調(diào)用事件處理函數(shù),如果參數(shù)為true,則表示在事件捕獲階段調(diào)用處理函數(shù)。請(qǐng)看例子。
事件代理
在實(shí)際的開發(fā)當(dāng)中,利用事件流的特性,我們可以使用一種叫做事件代理的方法。
<ul id="color-list"> <li>red</li> <li>yellow</li> <li>blue</li> <li>green</li> <li>black</li> <li>white</li> </ul>
如果點(diǎn)擊頁面中的li元素,然后輸出li當(dāng)中的顏色,我們通常會(huì)這樣寫:
(function(){
var color_list = document.getElementById('color-list');
var colors = color_list.getElementsByTagName('li');
for(var i=0;i<colors.length;i++){
colors[i].addEventListener('click',showColor,false);
};
function showColor(e){
var x = e.target;
alert("The color is " + x.innerHTML);
};
})();
利用事件流的特性,我們只綁定一個(gè)事件處理函數(shù)也可以完成:
(function(){
var color_list = document.getElementById('color-list');
color_list.addEventListener('click',showColor,false);
function showColor(e){
var x = e.target;
if(x.nodeName.toLowerCase() === 'li'){
alert('The color is ' + x.innerHTML);
}
}
})();
使用事件代理的好處不僅在于將多個(gè)事件處理函數(shù)減為一個(gè),而且對(duì)于不同的元素可以有不同的處理方法。假如上述列表元素當(dāng)中添加了其他的元素(如:a、span等),我們不必再一次循環(huán)給每一個(gè)元素綁定事件,直接修改事件代理的事件處理函數(shù)即可。
冒泡還是捕獲?
對(duì)于事件代理來說,在事件捕獲或者事件冒泡階段處理并沒有明顯的優(yōu)劣之分,但是由于事件冒泡的事件流模型被所有主流的瀏覽器兼容,從兼容性角度來說還是建議大家使用事件冒泡模型。
IE瀏覽器兼容
IE瀏覽器對(duì)addEventListener兼容性并不算太好,只有IE9以上可以使用。
要兼容舊版本的IE瀏覽器,可以使用IE的attachEvent函數(shù)
object.setCapture();
object.attachEvent(event, function)
兩個(gè)參數(shù)與addEventListener相似,分別是事件和處理函數(shù),默認(rèn)是事件冒泡階段調(diào)用處理函數(shù),要注意的是,寫事件名時(shí)候要加上"on"前綴("onload"、"onclick"等)。
以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。
相關(guān)文章
JavaScript實(shí)現(xiàn)動(dòng)態(tài)表格效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)動(dòng)態(tài)表格效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06淺談JS讀取DOM對(duì)象(標(biāo)簽)的自定義屬性
下面小編就為大家?guī)硪黄獪\談JS讀取DOM對(duì)象(標(biāo)簽)的自定義屬性。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11將input框中輸入內(nèi)容顯示在相應(yīng)的div中【三種方法可選】
本篇文章主要介紹了在input框中輸入內(nèi)容,會(huì)相應(yīng)的顯示在下面的div中的不同做法:js方法;jQuery方法;AngularJs方法,具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-05-05基于JavaScript實(shí)現(xiàn)猜數(shù)字游戲代碼實(shí)例
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)猜數(shù)字游戲代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07