Mozilla瀏覽器提供了一個(gè)JavaScript的綁定事件監(jiān)聽器的函數(shù)addEventListener
document.getElementById("button1").addEventListener("click",callback,isCapture);
其中各個(gè)參數(shù)說明如下:
- "click" 代表注冊(cè)的什么事件。“click”代表的自然是點(diǎn)擊事件,注意前面不加“on”前綴。也可以是其他事件,去掉“on”前綴即可。
- callback 回調(diào)函數(shù),當(dāng)事件被觸發(fā)時(shí)調(diào)用該函數(shù)。
- isCapture 是否在捕獲階段執(zhí)行回調(diào)。默認(rèn)為false。
下面來說一下第三個(gè)參數(shù) isCapture。它是一個(gè)boolean類型的值。說到它就不得不提一下JavaScript中的事件觸發(fā)經(jīng)歷的兩個(gè)階段:捕獲階段和冒泡階段。
從圖中可見都是嵌套關(guān)系。我們假定點(diǎn)擊了最內(nèi)層的text元素,觸發(fā)了它的onclick事件。
但是實(shí)際上因?yàn)槭乔短椎脑颍c(diǎn)擊了最內(nèi)層的text也相當(dāng)于點(diǎn)擊了它的父元素div,也相當(dāng)于點(diǎn)擊了父元素的父元素body……也相當(dāng)于點(diǎn)擊了window,那么如果這些外層元素也有onclick的點(diǎn)擊事件,它們也應(yīng)當(dāng)被觸發(fā),現(xiàn)在的問題是,是在什么時(shí)候被觸發(fā)?
圖中可見有兩個(gè)階段
- 先從最外面開始(也就是window開始)向內(nèi)推進(jìn),直到定位到觸發(fā)的元素text。這一過程叫“捕獲過程”。
- 然后從該元素開始,又向上級(jí)冒泡。該過程為“冒泡過程”。
顯然,對(duì)于這個(gè)嵌套鏈上的每個(gè)元素,它的觸發(fā)按數(shù)即可以在捕獲階段被執(zhí)行,也可以在冒泡階段被執(zhí)行。
所以,addEventListener的第三個(gè)參數(shù)正是指定這個(gè)觸發(fā)時(shí)段的。默認(rèn)情況是false,也就是在冒泡階段被執(zhí)行;如果指派為true,則在捕獲階段被執(zhí)行。
用一個(gè)簡(jiǎn)單的實(shí)驗(yàn)可以說明問題:
假設(shè)現(xiàn)在一個(gè)HTML界面有三個(gè)呈嵌套關(guān)系的元素
<div id="outer" >
<div id="middle" >
<input type="button" id="inner" value="inner"/>
</div>
</div>
最外層是outer,中間是middle,內(nèi)部是inner。
下面是三個(gè)元素綁定點(diǎn)擊事件:
window.onload=function(){
document.getElementById("inner").addEventListener("click",show("inner"),false);
document.getElementById("middle").addEventListener("click",show("middle"),false);
document.getElementById("outer").addEventListener("click",show("outer"),false);
}
function show(i){
return function(){
console.log(i);
}
}
點(diǎn)擊對(duì)應(yīng)元素,就會(huì)在控制臺(tái)打印出相應(yīng)信息。下面分別修改三個(gè)boolean參數(shù),觀察輸出結(jié)果
OUTPUT的結(jié)果左邊先打印,右邊后打印。我們舉兩個(gè)結(jié)果說明:
- isCapture分別被設(shè)置為TFF的時(shí)候,點(diǎn)擊最內(nèi)層inner的按鈕,由于outer、middle設(shè)置的為false,那么它們?cè)诓东@階段不會(huì)被觸發(fā),控制流到達(dá)inner,此時(shí)先輸出inner,然后開始返回,也就是向上級(jí)冒泡,所以依次觸發(fā)middle、outer。
- isCapture分別被設(shè)置為TTF的時(shí)候,點(diǎn)擊最內(nèi)層inner按鈕,由于outer設(shè)置為false,那么它在進(jìn)入的階段不會(huì)被觸發(fā),但是當(dāng)遇到middle時(shí)候,因?yàn)槭莟rue,所以會(huì)被觸發(fā),先輸出middle,然后輸出inner,最后在返回的冒泡階段,outer被觸發(fā),最后輸出outer。