JQuery DOM 事件冒泡

什麼是冒泡

在頁面上能夠有多個事件,也能夠多個元素響應同一個事件。假設網頁上有兩個元素,其中一個元素嵌套在另外一個元素裏,而且都被綁定了click事件,同時body元素上也綁定了click事件。
javascript

<div id="content">
	外層div元素
	<span>內層span元素</span>
	外層div元素
</div>

<script type="text/javascript">
$(function(){
	// 爲span元素綁定click事件
	$('span').bind("click",function(){
		var txt = $('#msg').html() + "<p>內層span元素被點擊.<p/>";
		$('#msg').html(txt);
	});
	// 爲div元素綁定click事件
	$('#content').bind("click",function(){
	    var txt = $('#msg').html() + "<p>外層div元素被點擊.<p/>";
		$('#msg').html(txt);
	});
	// 爲body元素綁定click事件
	$("body").bind("click",function(){
		var txt = $('#msg').html() + "<p>body元素被點擊.<p/>";
		$('#msg').html(txt);
	});
})
</script>

當單擊內部span元素,即觸發span元素的click事件時,會輸出3條記錄。只單擊內部span元素,就會觸發外部div元素和body元素 上綁定的click事件。這是由事件冒泡引發的。在單擊span元素的同時,也單擊了包含span元素的元素div和包含div元素的元素body,而且 每個元素都會按照特定的順序響應click事件。html

元素的click事件會按照如下順序「冒泡」。java

  1. <span>瀏覽器

  2. <div>函數

  3. <body>spa

之因此稱爲冒泡,是由於事件會按照DOM的層次結構像水泡同樣不斷向上直至頂端。code

事件冒泡引起的問題

事件冒泡可能會引發預料以外的效果。上例中,原本只想觸發<span>元素的click事件,然而<div>元素 和<body>元素的click事件也同時被觸發了。所以,有必要對事件的做用範圍進行限制。當單擊<span>元素時,只觸 發<span>元素的click事件,而不觸發<div>元素和<body>元素的click事件:當單 擊<div>元素時,只觸發<div>元素的click事件,而不觸發<body>元素的click事件。orm

事件對象htm

因爲IE-DOM和標準DOM實現事件對象的方法各不相同,致使在不一樣瀏覽器中獲取事件對象變得比較困難。針對這個問題,JQuery進行了必要的擴展和封裝,從而使得在任何瀏覽器中都能很輕鬆地獲取事件對象以及事件對象的一些屬性。對象

在程序中使用事件對象很是簡單,只須要爲函數添加一個參數,jQuery代碼以下:

$("element").bind("click",function(event){   
	//event  :  事件對象   
	//...   
});

這樣,當單擊「element」元素時,事件對象就被建立了。這個事件對象只有事件處理函數才能訪問到。事件處理函數執行完畢後,事件對象就被銷燬。

中止事件冒泡

中止事件冒泡能夠阻止事件中其餘對象的事件處理函數被執行。在JQuery中提供了stopPropagation()方法來中止事件冒泡。

$(function(){
   	// 爲span元素綁定click事件
	$('span').bind("click",function(event){
		var txt = $('#msg').html() + "內層span元素被點擊";
		$('#msg').html(txt);
		event.stopPropagation();    //  阻止事件冒泡
	});
})

當單擊<span>元素時,只會觸發<span>元素上的click事件,而不會觸發<div>元素和<body>元素的click事件。能夠用一樣的方法解決<div>元素上的冒泡問題。

$('#content').bind("click",function(event){   
    var txt = $('#msg').html() + "<p>外層div元素被點擊.<p/>";   
    $('#msg').html(txt);   
    event.stopPropagation();    //  阻止事件冒泡   
});

這樣,當單擊<span>元素或者<div>元素時,就只會輸出相應的內容,而不會輸出其餘的內容。

阻止默認行爲

網頁中的元素有本身默認的行爲,例如,單擊超連接後會跳轉、單擊「提交」按鈕後表單會提交,有時須要阻止元素的默認行爲。

在JQuery中,提供了preventDefault()方法來阻止元素的默認行爲。

舉一個例子,在項目中,常常須要驗證表單,在單擊「提交」按鈕時,驗證表單內容,例如某元素是不是必填字段,某元素長度是否夠6位等,當表單不符合提交條件時,要阻止表單的提交(默認行爲)。

<form action="test.html">
用戶名:<input type="text" id="username" />
<br/>
<input type="submit" value="提交" id="sub"/>
</form>

$(function(){
   $("#sub").bind("click",function(event){
         var username = $("#username").val();  //獲取元素的值
         if(username==""){     //判斷值是否爲空
		     $("#msg").html("<p>文本框的值不能爲空.</p>");  //提示信息
		     event.preventDefault();  //阻止默認行爲 ( 表單提交 )
		 }
   })
})

當用戶名爲空時,單擊「提交」按鈕,會出現提示,而且表單不能提交。只有在用戶名裏輸入內容後,才能提交表單。可見,preventDefault()方法能阻止表單的提交行爲。

若是想同時對事件對象中止冒泡和默認行爲,能夠在事件處理函數中返同false。這是對在事件對象上同時調用stopPrapagation()方法和preventDefault()方法的一種簡寫方式。

在表單的例子中,能夠把 event.preventDefault(); 改寫爲: return false;

也能夠把事件冒泡例子中的 event.stopPropaqation(); 改寫爲: return false;

事件捕獲

事件捕獲和事件冒泡是恰好相反的兩個過程,事件捕獲是從最頂端往下開始觸發。仍是冒泡事件的例子,其中元素的click事件會按照如下順序捕獲。

  1. <body>

  2. <div>

  3. <span>

很顯然,事件捕獲是從最外層元素開始,而後再到最裏層元素。所以綁定的click事件,首先會傳遞給<body>元素,而後傳遞給<div>元素,最後才傳遞給<span>元素。

遺憾的是,並不是全部主流瀏覽器都支持事件捕獲,而且這個缺陷沒法經過JavaScript來修復。JQuery不交持事件捕獲,若是讀者須要使用事件捕獲,請直接使用原生的JavaScript。

相關文章
相關標籤/搜索