事件冒泡和事件捕獲示意圖:
一、事件冒泡
執行個體:
<!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;
}