天天看點

事件冒泡和事件捕獲

事件冒泡和事件捕獲示意圖:

事件冒泡和事件捕獲

一、事件冒泡

執行個體:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>事件冒泡</title>
<style>
*{margin:0; padding:0;}
</style>
<script type="text/javascript">
window.onload = function(){
	var div1 = document.getElementsByTagName('div')[0];
	var oSpan = document.getElementsByTagName('span')[0];
	var oBody = document.getElementsByTagName('body')[0];
	
	oSpan.onclick = function(e){
		this.style.background = 'red';
		var ev = e || event;
		alert('red');	
	}
	
	div1.onclick = function(e){
		this.style.background = 'green';
		var ev = e || event;
		alert('green');	
	}
	
	oBody.onclick = function(e){
		this.style.background = 'blue';
		var ev = e || event;
		alert('blue');	
	}
}
</script>
</head>

<body>
<div class="div1">
 	<span>測試事件冒泡</span>
</div>
</body>
</html>
           

結果依次彈出‘red’,‘green’,‘blue’,是以我們觸發span元素,連同父級元素一起觸發了,這就是事件冒泡。從裡到外。

解決辦法:阻止事件冒泡,但是有相容問題,是以下面提供一個寫好的無相容問題的阻止冒泡函數

function stopBubble(e) {
	
		// 如果提供了事件對象,則這是一個非IE浏覽器
	
		if ( e && e.stopPropagation ) {
	
			// 是以它支援W3C的stopPropagation()方法 
	
			e.stopPropagation();
	
		} else { 
	
			// 否則,我們需要使用IE的方式來取消事件冒泡
	
			window.event.cancelBubble = true;
	
		}
	
	}
           

那解決上面span那個事件冒泡的代碼,寫好的在下面:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>阻止事件冒泡</title>
<style>
*{margin:0; padding:0;}
</style>
<script type="text/javascript">
window.onload = function(){
	var div1 = document.getElementsByTagName('div')[0];
	var oSpan = document.getElementsByTagName('span')[0];
	var oBody = document.getElementsByTagName('body')[0];
	
	oSpan.onclick = function(e){
		this.style.background = 'red';
		var ev = e || event;
		stopBubble(e);
		alert('red');	
	}
	
	div1.onclick = function(e){
		this.style.background = 'green';
		var ev = e || event;
		alert('green');	
	}
	
	oBody.onclick = function(e){
		this.style.background = 'blue';
		var ev = e || event;
		alert('blue');	
	}
	
	//阻止事件冒泡的相容性寫法
	
	function stopBubble(e) {
	
		// 如果提供了事件對象,則這是一個非IE浏覽器
	
		if ( e && e.stopPropagation ) {
	
			// 是以它支援W3C的stopPropagation()方法 
	
			e.stopPropagation();
	
		} else { 
	
			// 否則,我們需要使用IE的方式來取消事件冒泡
	
			window.event.cancelBubble = true;
	
		}
	
	}
}
</script>
</head>

<body>
<div class="div1">
 	<span>測試事件冒泡</span>
</div>
</body>
</html>
           

這樣的話,再點選時,隻會觸發span的事件,背景顔色變成紅色。

有事件冒泡的話,就會有相反的事件捕獲~~~~~

二、事件捕獲

執行個體:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>事件捕獲</title>
<style>
*{margin:0; padding:0;}
</style>
<script type="text/javascript">
window.onload = function(){
	var div1 = document.getElementsByTagName('div')[0];
	var oSpan = document.getElementsByTagName('span')[0];
	var oBody = document.getElementsByTagName('body')[0];
	
	oSpan.addEventListener('click',function(){
		this.style.background = 'red';
		alert('red');	
	},true);
	
	div1.addEventListener('click',function(){
		this.style.background = 'green';
		alert('green');	
	},true);
	
	oBody.addEventListener('click',function(){
		this.style.background = 'blue';
		alert('blue');	
	},true);
	
	
}
</script>
</head>

<body>
<div class="div1">
 	<span>測試事件冒泡</span>
</div>
</body>
</html>
           

結果依次彈出‘blue’,‘green’,‘red’,是以我們觸發span元素,會先觸發最外層父級,在一直往裡執行,這就是事件捕獲。從外到裡。

使用addEventListener綁定事件的時候,第三個參數為true表示捕獲,為false表示事件冒泡。

阻止事件捕獲:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>阻止事件捕獲</title>
<style>
*{margin:0; padding:0;}
</style>
<script type="text/javascript">
window.onload = function(){
	var div1 = document.getElementsByTagName('div')[0];
	var oSpan = document.getElementsByTagName('span')[0];
	var oBody = document.getElementsByTagName('body')[0];
	
	oSpan.addEventListener('click',function(e){
		this.style.background = 'red';
		var e = e || event;
		alert('red');	
	},true);
	
	div1.addEventListener('click',function(e){
		this.style.background = 'green';
		var e = e || event;
		alert('green');	
	},true);
	
	oBody.addEventListener('click',function(e){
		this.style.background = 'blue';
		var e = e || event;
		stopBubble(e);
		alert('blue');	
	},true);
	
	function stopBubble(e) {

		// 如果提供了事件對象,則這是一個非IE浏覽器
	
		if ( e && e.stopPropagation ) {
	
			// 是以它支援W3C的stopPropagation()方法 
	
			e.stopPropagation();
	
		} else { 
	
			// 否則,我們需要使用IE的方式來取消事件冒泡
	
			window.event.cancelBubble = true;
	
		}
	
	}
}
</script>
</head>

<body>
<div class="div1">
 	<span>測試事件冒泡</span>
</div>
</body>
</html>
           

顯示結果:背景為藍色,把往裡傳遞的事件阻止了。

延伸

阻止事件預設行為;(因為像文字、圖檔等在浏覽器中有預設行為,用下面寫法去阻止)

無相容寫法:

function stopDefault( e ) {

     // 阻止預設浏覽器動作(W3C)

     if ( e && e.preventDefault ) {

         e.preventDefault();

     } else {

        // IE中阻止函數器預設動作的方式

        window.event.returnValue = false;

    }

    return false;

}