1. 程式人生 > >11.JS-事件流-冒泡、捕獲

11.JS-事件流-冒泡、捕獲

事件流

頁面接受事件的順序

 DOM事件流

當事件發生時,事件會在該元素節點和根節點之間的路徑進行傳播,傳播過程中所遇到的節點都會接受該事件

                         冒泡:從最具體元素傳播最不具體的元素

                事件發生的元素節點傳播到根節點

            捕獲:從最不具體的元素傳播到最具體的元素

                根節點傳播到事件發生的具體節點

                注意:IE中只有冒泡階段,非IE中既有冒泡也有捕獲

 阻止事件冒泡

            event.stopPropagation()

事件傳遞定義了元素事件觸發的順序。 如果你將 <p> 元素插入到 <div> 元素中,使用者點選 <p> 元素, 哪個元素的 "click" 事件先被觸發呢?

在 冒泡 中,內部元素的事件會先被觸發,然後再觸發外部元素,即: <p> 元素的點選事件先觸發,然後會觸發 <div> 元素的點選事件。

 在 捕獲 中,外部元素的事件會先被觸發,然後才會觸發內部元素的事件,即: <div> 元素的點選事件先觸發 ,然後再觸發 <p> 元素的點選事件。

比如:我設定了3個div,層層巢狀

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title></title>
</head>
	<style type="text/css">
		#box1{
			width: 1000px;
			height: 500px;
			margin:  0 auto;
			border: 1px solid #233;
		}
		#box2{
			width: 700px;
			height:400px;
			border: 1px solid #233;
			margin:  0 auto;
		}
		#box3{
			width:500px;
			height: 300px;
			margin:  0 auto;
			border: 1px solid #233;
		}

	</style>
<body>
	
	<div id="box1">
		box1
		<div id="box2">
			box2
			<div id="box3">box3</div>
		</div>
	</div>
</body>
</html>

然後為它們都註冊一個點選事件

var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');

function addEvent(obj,type,fn){

    if(obj.addEventListener){
	    obj.addEventListener(type,fn,false);			
    }else {				
	    obj.attachEvent("on"+type,fn);
    }
}

addEvent(box1,'click',function(event){alert('我是box1')});
addEvent(box2,'click',function(event){alert('我是box2')});
addEvent(box3,'click',function(event){
	alert('我是box3')
	//阻止事件冒泡
	//event.stopPropagation();
});

 事件流順序預設為false,即冒泡。

這個時候當你點選box3時,會彈出'我是box3'的視窗,緊接著依次彈出'我是box2'和'我是box1'的視窗。

想要阻止這種行為出現,可以在box3的註冊事件函式內新增event.stopPropagation();,阻止事件冒泡

若將事件流順序改為true,即捕獲。

當點選box3時,彈出視窗的順序會和冒泡的相反。

最後,再提醒一次,想要看到捕獲階段的效果,請在非IE瀏覽器上執行,因為IE瀏覽器只有冒泡階段。