??JavaScript 與 HTML 之間的交互是通過事件實現(xiàn)的峭弟。事件蒸殿,就是文檔或瀏覽器窗口中發(fā)生的一些特定的交互瞬間触趴。既然事件是由一些交互所產(chǎn)生的力奋,那么就要了解這些事件是由頁面中的哪一部分交互所產(chǎn)生。
事件流
??事件流描述的是從頁面中接收事件的順序钞钙。但有意思的是鳄橘,IE 和 Netscape 開發(fā)團隊居然提出了差不多是完全相反的事件流的概念。IE 的事件流是事件冒泡流芒炼,而 Netscape Communicator 的事件流是事件捕獲流瘫怜。
-
事件冒泡
??IE提出的事件流是事件冒泡流,這種事件流傳播是由內(nèi)向外進行傳遞本刽。即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節(jié)點)接收鲸湃,然后逐級向上傳播到較為不具體的節(jié)點(文檔)。比如:
<!DOCTYPE html>
<html>
<head>
<title>事件冒泡</title>
</head>
<body>
<div>
<button></button>
</div>
</body>
</html>
在上述例子中子寓,假使你點擊了其中的button標簽暗挑,那么由事件冒泡所給的定義而言,其事件流的傳播流程為button --> div --> body --> html --> document斜友。即當點擊了button按鈕時炸裆,事件便由事件源開始一層一層向外層元素傳遞,直到傳遞到document元素上鲜屏。
??此外烹看,所有現(xiàn)代瀏覽器都支持事件冒泡国拇,但在具體實現(xiàn)上還是有一些差別。IE5.5 及更早版本中的事件冒泡會跳過<html>元素(從<body>直接跳到 document)惯殊。IE9酱吝、Firefox、Chrome 和 Safari 則將事件一直冒泡到 window 對象土思。
-
事件捕獲
??Netscape Communicator 提出的事件流傳播方式為事件捕獲流务热,而事件捕獲流則是從外向內(nèi)傳播。即事件捕獲的思想是不太具體的節(jié)點應(yīng)該更早接收到事件己儒,而最具體的節(jié)點應(yīng)該最后接收到事件崎岂。事件捕獲的用意在于在事件到達預(yù)定目標之前捕獲它。這種思想恰恰和事件冒泡幾乎完全相反址愿。
??還以上面的為例该镣,按照事件捕獲的思想,其事件傳播流程為:document --> html -->body --> div --> button响谓。在事件捕獲過程中,document 對象首先接收到button上的 click 事件省艳,然后事件沿 DOM 樹依次向下(由外向內(nèi))娘纷,一直傳播到事件的實際目標,即事件源button元素跋炕。
??注意赖晶,雖然事件捕獲是 Netscape Communicator 唯一支持的事件流模型,但 IE9辐烂、Safari遏插、Chrome、Opera和 Firefox 目前也都支持這種事件流模型纠修。由于老版本的瀏覽器不支持胳嘲,因此很少有人使用事件捕獲。
DOM事件流
??“DOM2級事件”規(guī)定的事件流包括三個階段:事件捕獲階段扣草、處于目標階段和事件冒泡階段了牛。首先發(fā)生的是事件捕獲,為截獲事件提供了機會辰妙。然后是實際的目標接收到事件鹰祸。最后一個階段是冒泡階段,可以在這個階段對事件做出響應(yīng)密浑。如下:
<!DOCTYPE html>
<html>
<head>
<title>DOM事件流</title>
</head>
<body>
<div>
<button></button>
</div>
</body>
</html>
??在 DOM 事件流中蛙婴,當點擊button元素后,實際的目標(<button>元素)在捕獲階段不會接收到事件尔破。這意味著在捕獲階段街图,事件從 document 到<html>再到<body>最后到<div>就停止了浇衬。下一個階段是“處于目標”階段,于是事件在<div>上發(fā)生台夺,并在事件處理中被看成冒泡階段的一部分径玖。然后,冒泡階段發(fā)生颤介,事件又傳播回document梳星。
事件阻止
-
event.stopPropagation()
-
event.cancleBubble = true
??這是阻止事件冒泡的兩種方法,不讓事件向document上蔓延滚朵,但是默認事件任然會執(zhí)行冤灾,當你對一個鏈接使用這兩方法中的一個時,如果點擊鏈接辕近,這個鏈接仍然會被打開韵吨,但是事件冒泡卻被阻止了。其兼容寫法為:
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;
}
-
event.preventDefault()
-
event.returnValue = false
??這是阻止默認行為的兩種方式移宅,第一種是W3C提供的方法归粉,第二種是IE提出的方法。當對一個鏈接使用以上兩種方法之一時漏峰,鏈接不會被打開糠悼,但是會發(fā)生事件冒泡;
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue= false;
}
-
return false
??這個方法能夠?qū)崿F(xiàn)同時阻止默認行為和事件冒泡浅乔。即當對一個鏈接使用時倔喂,會使這個鏈接不能實現(xiàn)點擊跳轉(zhuǎn)頁面,并且也不會沿dom樹向上進行冒泡靖苇。