stopPropagation, preventDefault 和 return false 的區別


因為有父, 子節點同在, 因為有監聽事件和瀏覽器默認動作之分. 使用 JavaScript 時為了達到預期效果經常需要阻止事件和動作執行. 一般我們會用到三種方法, 分別是 stopPropagation()preventDefault() 和 return false. 它們之間有什么區別, 該何時使用呢? 將在本文中進行講解.

 

術語

監聽事件, 在在節點上能被監聽的頁面操作. 如: select 節點的 change 事件, a 節點的 click 事件.
瀏覽器默認動作, 指特定頁面元素上帶有的功能. 如: 點擊 a 鏈接節點的跳轉動作, 表單提交動作.

stopPropagation()

講stopPropagation方法之前必需先給大家講解一下js的事件代理。

事件代理用到了兩個在JavaSciprt事件中常被忽略的特性:事件冒泡以及目標元素。當一個元素上的事件被觸發的時候,比如說鼠標點擊了一個按鈕,同樣的事件將會在那個元素的所有祖先元素中被觸發。這一過程被稱為事件冒泡;這個事件從原始元素開始一直冒泡到DOM樹的最上層。對任何一個事件來說,其目標元素都是原始元素,在我們的這個例子中也就是按鈕。目標元素它在我們的事件對象中以屬性的形式出現。使用事件代理的話我們可以把事件處理器添加到一個元素上,等待事件從它的子級元素里冒泡上來,並且可以很方便地判斷出這個事件是從哪個元素開始的。

stopPropagation方法就是起到阻止js事件冒泡的作用,看一段代碼。


<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xHTML1/DTD/xHTML1-transitional.dtd">
<HTML XMLns="http://www.w3.org/1999/xHTML" lang="gb2312">
<head>
<title> 阻止JS事件冒泡傳遞(cancelBubble 、stopPropagation)</title>
<meta name="keywords" content="JS,事件冒泡,cancelBubble,stopPropagation" />
<script>
function doSomething (obj,evt) {
 alert(obj.id);
 var e=(evt)?evt:window.event;
 if (window.event) {
  e.cancelBubble=true;// ie下阻止冒泡
 } else {
  //e.preventDefault();
  e.stopPropagation();// 其它瀏覽器下阻止冒泡
 }
}
</script>
</head>
<body>
<div id="parent1" onclick="alert(this.id)" style="width:250px;
 <p>This is parent1 div.</p>
 <div id="child1" onclick="alert(this.id)" style="width:200px;
  <p>This is child1.</p>
 </div>
 <p>This is parent1 div.</p>
</div>
<br />
<div id="parent2" onclick="alert(this.id)" style="width:250px;">
 <p>This is parent2 div.</p>
 <div id="child2" onclick="doSomething(this,event);" style="width:200px;">
  <p>This is child2. Will bubble.</p>
 </div>
 <p>This is parent2 div.</p>
</div>
</body>
</HTML> 

 有時我們希望事件在特定節點執行完之后不再傳遞, 可以使用事件對象的 stopPropagation() 方法.例如以下實例:

假設頁面上存在一個浮動彈出層, 顯示在最前面, 當點擊彈出層以外頁面區域時, 隱藏彈出層. 為了做到這樣的效果, 我們會監聽 documentElement 的 click 事件, 一旦事件被觸發即隱藏彈出層. 但是...

這顯然存在問題. 當用戶點擊彈出層時, 我們不希望它隱藏掉. 但因為事件的冒泡傳遞, documentElement 的 click 事件也會被觸發. 這個時候, 我們可以監聽彈出層的 click 事件, 並使用 stopPropagation() 方法阻止冒泡. 請參考下面的代碼.

// 在彈出對話框上點擊時, 不進行任何頁面操作, 並阻止冒泡
document.getElementById('dialog').onclick = function(ev) {
	ev.stopPropagation();
};
 
// 在 documentElement 節點上監聽到點擊事件時, 隱藏對話框
document.documentElement.onclick = function(ev) {
	document.getElementById('dialog').style.display = 'none';
};

stopPropagation() 相當好用, 可是 IE8 及以前版本都不支持. IE 的事件對象包含特有的屬性 cancelBubble, 只要將它賦值為 false 即可阻止事件繼續. 如:

// 在彈出對話框上點擊時, 不進行任何頁面操作, 並阻止冒泡
document.getElementById('dialog').onclick = function(ev) {
	ev.cancelBubble = false;
};

preventDefault()

preventDefault方法就是可以阻止它的默認行為的發生而發生其他的事情(官方解釋:該方法將通知 Web 瀏覽器不要執行與事件關聯的默認動作(如果存在這樣的動作)。例如,如果 type 屬性是 "submit",在事件傳播的任意階段可以調用任意的事件句柄,通過調用該方法,可以阻止提交表單。注意,如果 Event 對象的 cancelable 屬性是 fasle,那么就沒有默認動作,或者不能阻止默認動作。無論哪種情況,調用該方法都沒有作用。)

一個帶事件監聽的鏈接代碼如下:

<a href="http://w3c.org" onclick="alert('JavaScript Click Event');">點擊鏈接</a>

點擊該鏈接, 顯示對話框后跳轉頁面. 由此可知, 除了執行監聽事件還會觸發瀏覽器默認動作; 執行監聽事件在前, 觸發瀏覽器默認動作在后.

這里有個經典示例, 我們希望點擊鏈接在新窗口打開頁面, 但不希望當前頁面跳轉. 這個時候可以使用 preventDefault() 阻止后面將要執行的瀏覽器默認動作.

<a id="link" href="http://w3c.org">W3C 首頁鏈接</a>
 
<script>
// 在新窗口, 打開頁面
document.getElementById('link').onclick = function(ev) {
	// 阻止瀏覽器默認動作 (頁面跳轉)
	ev.preventDefault();
	// 在新窗口打開頁面
	window.open(this.href);
};
</script>

return false

退出執行, return false 之后的所有觸發事件和動作都不會被執行. 有時候 return false 可以用來替代 stopPropagation() 和 preventDefault(), 比如我們上面新窗口打開鏈接的例子, 如:

<a id="link" href="http://w3c.org">W3C 首頁鏈接</a>
 
<script>
// 在新窗口, 打開頁面
document.getElementById('link').onclick = function(ev) {
	// 在新窗口打開頁面
	window.open(this.href);
	// 退出執行 (在監聽事件之后執行的瀏覽器默認動作將不會被執行)
	return false;
};
</script>

有人認為 return false = stopPropagation() + preventDefault(), 其實是錯的. return false 不但阻止事件, 還可以返回對象, 跳出循環等... 方便地一刀切而不夠靈活, 濫用易出錯.

 

鏈接:http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f73f6b8a87463e838448e435061e5a27a5e6656050599196293447f41400fdf040216b5537b7ed8ac81d99ecce6e79df73673742c05612a54af39d5125b760c71caeef45f0ba8666c0f09384c2401697135375c2b0dc1e57488c78f16467b4f2ca0f4b19&p=882a9546d1855afc57ef8a35570e8b&newp=9c7fc64ad4934eaf5beac639490798231610db2151d7d217&user=baidu&fm=sc&query=preventDefault&qid=d7add83a00020c1d&p1=5

  http://www.jb51.net/article/46379.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM