由於有父, 子節點同在, 由於有監聽事件和瀏覽器默認動做之分. 使用 JavaScript 時爲了達到預期效果常常須要阻止事件和動做執行. 通常咱們會用到三種方法, 分別是 stopPropagation()
, preventDefault()
和 return false
. 它們之間有什麼區別, 該什麼時候使用呢? 將在本文中進行講解.javascript
監聽事件, 在在節點上能被監聽的頁面操做. 如: select 節點的 change 事件, a 節點的 click 事件.
瀏覽器默認動做, 指特定頁面元素上帶有的功能. 如: 點擊 a 連接節點的跳轉動做, 表單提交動做.html
講stopPropagation方法以前必需先給你們講解一下js的事件代理。java
事件代理用到了兩個在JavaSciprt事件中常被忽略的特性:事件冒泡以及目標元素。當一個元素上的事件被觸發的時候,好比說鼠標點擊了一個按鈕,一樣的事件將會在那個元素的全部祖先元素中被觸發。這一過程被稱爲事件冒泡;這個事件從原始元素開始一直冒泡到DOM樹的最上層。對任何一個事件來講,其目標元素都是原始元素,在咱們的這個例子中也就是按鈕。目標元素它在咱們的事件對象中以屬性的形式出現。使用事件代理的話咱們能夠把事件處理器添加到一個元素上,等待事件從它的子級元素裏冒泡上來,而且能夠很方便地判斷出這個事件是從哪一個元素開始的。瀏覽器
stopPropagation方法就是起到阻止js事件冒泡的做用,看一段代碼。this
有時咱們但願事件在特定節點執行完以後再也不傳遞, 可使用事件對象的 stopPropagation()
方法.例如如下實例:spa
假設頁面上存在一個浮動彈出層, 顯示在最前面, 當點擊彈出層之外頁面區域時, 隱藏彈出層. 爲了作到這樣的效果, 咱們會監聽 documentElement
的 click 事件, 一旦事件被觸發即隱藏彈出層. 可是....net
這顯然存在問題. 當用戶點擊彈出層時, 咱們不但願它隱藏掉. 但由於事件的冒泡傳遞, 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 便可阻止事件繼續. 如:code
// 在彈出對話框上點擊時, 不進行任何頁面操做, 並阻止冒泡 document.getElementById('dialog').onclick = function(ev) { ev.cancelBubble = false; }; |
preventDefault方法就是能夠阻止它的默認行爲的發生而發生其餘的事情(官方解釋:該方法將通知 Web 瀏覽器不要執行與事件關聯的默認動做(若是存在這樣的動做)。例如,若是 type 屬性是 "submit",在事件傳播的任意階段能夠調用任意的事件句柄,經過調用該方法,能夠阻止提交表單。注意,若是 Event 對象的 cancelable 屬性是 fasle,那麼就沒有默認動做,或者不能阻止默認動做。不管哪一種狀況,調用該方法都沒有做用。)htm
一個帶事件監聽的連接代碼以下:
<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
能夠用來替代 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