1. 程式人生 > >JavaScript的捕獲和冒泡

JavaScript的捕獲和冒泡

今天,複習了一下捕獲和冒泡,講道理,以前看的好多東西都忘了。。

1、冒泡

先看一段程式碼,不是很複雜

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<script type="text/javascript" src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script>
	
</head>
<body>
	<div id = "d1">
		<div id="d2">
			<div id ="d3" style="width: 100px;height: 100px;background: #000"></div>
		</div>
	</div>
	<hr/>
	<div id ="d4" style="width: 100px;height: 100px;background: #000"></div>
</body>
<script type="text/javascript">
		$("#d1").click(function(){
			alert("I am d1");
		});	
		$("#d2").click(function() {
			alert("I am d2");
		});
		$("#d3").click(function(){
			alert("I am d3");
		});
		$("body").click(function(){
			alert("I am body");
		});	
	</script>
</html>


運行於chrome和IE瀏覽器,點選上面的黑塊,分別彈出d3、d2、d1、body;點選下面的黑塊,彈出body

這就是冒泡,從最精準的dom元素到最不精準的dom元素繫結的點選事件都會觸發,只要你點了一下。。

那有時候應用的時候我們不需要冒泡帶來的事件效果,那麼如何阻止冒泡呢?再做個示範,將d2部分的click程式碼改成下面這個樣子

		$("#d2").click(function(event) {
			alert("I am d2");	
			event.stopPropagation();
		});

這時候開啟chrome,我們發現彈出的只有d3、d2,點選事件在進入d2的事件函式中的時候,遇到stopPropagation()的函式,導致事件取消傳播。

但是,在IE環境下執行卻照舊會彈出d3、d2、d1、body,原來IE下是不相容的。。。那隻好改一改了

		$("#d2").click(function(event) {
			alert("I am d2");	
			if (event.stopPropagation) { 
				// this code is for Mozilla and Opera 
				event.stopPropagation(); 
				//return false;
			} 
			else if (window.event) { 
				// this code is for IE 
				window.event.cancelBubble = true; 
				//return false;
			}
		});

以上這段程式碼,在chrome下還是成功的,但是我的IE不知道出了啥鬼問題,原始檔改了,但是IE開啟之後是之前的檔案,所以暫時還沒測試,另外如果直接return false的話有,也會終止當前事件的傳播的。但是現在由於特殊原因還沒測試。

2、捕獲

捕獲就是,當觸發點選事件的時候,會從祖先元素開始傳播到子孫元素。談到捕獲,需要提到Js裡的一個函式addEventListener(type,dosomething,true或者false),

type是監聽事件型別,dosomething是操作,true代表捕獲過程中觸發時間,false代表冒泡過程中觸發時間,w3c標準中規定其事件觸發順序是

祖先元素 ----->  子孫元素 ----->祖先元素

實際上,就是先捕獲,再冒泡

下面舉個例子,還是之前的頁面,不過更改了JavaScript

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script type="text/javascript">
     window.onload = function(){
            var od1 = document.getElementById("d1");
            var od2 = document.getElementById("d2");
            var od3 = document.getElementById("d3");
            var od4 = document.getElementById("d4");
            od1.addEventListener('click',function(){
                alert("I am d1");
            },false);
            od2.addEventListener('click',function(){
                alert("I am d2");
            },true);
        }
    </script>
</head>
<body>
<body>
    <div id = "d1">
        <div id="d2">
            <div id ="d3" style="width: 100px;height: 100px;background: #000"></div>
        </div>
    </div>
    <hr/>
    <div id ="d4" style="width: 100px;height: 100px;background: #000"></div>
</body>
</body>
</html>

由於先捕獲,則先彈出d2,然後在冒泡過程中再彈出d1,可以試著更改addEventListener的true和false看看彈出順序的變化。