stopPropagation, preventDefault 和 return false 的區別

由於有父, 子節點同在, 由於有監聽事件和瀏覽器默認動做之分. 使用 JavaScript 時爲了達到預期效果常常須要阻止事件和動做執行. 通常咱們會用到三種方法, 分別是 stopPropagation(), preventDefault() 和 return false. 它們之間有什麼區別, 該什麼時候使用呢? 將在本文中進行講解. javascript

術語

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

stopPropagation()

由於事件能夠在各層級的節點中傳遞, 無論是冒泡仍是捕獲, 有時咱們但願事件在特定節點執行完以後再也不傳遞, 可使用事件對象的stopPropagation() 方法. java

假設頁面上存在一個浮動彈出層, 顯示在最前面, 當點擊彈出層之外頁面區域時, 隱藏彈出層. 爲了作到這樣的效果, 咱們會監聽documentElement 的 click 事件, 一旦事件被觸發即隱藏彈出層. 可是... 瀏覽器

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

// 在彈出對話框上點擊時, 不進行任何頁面操做, 並阻止冒泡 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 便可阻止事件繼續. 如: spa

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

preventDefault()

一個帶事件監聽的連接代碼以下: code

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

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

這裏有個經典示例, 咱們但願點擊連接在新窗口打開頁面, 但不但願當前頁面跳轉. 這個時候可使用 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 不但阻止事件, 還能夠返回對象, 跳出循環等... 方便地一刀切而不夠靈活, 濫用易出錯.

相關文章
相關標籤/搜索