event事件對象有三種易混淆的方法,本文講述他們之間的區別:javascript
首先,咱們看看他們在MDN上的介紹:html
咱們來看一個代碼示例,當點擊一個form中的submit按鈕時會將form提交處理,此時若是使用Event.preventDefault,就能夠在點擊submit按鈕時避免表格提交。java
<form id="myForm" action="/my-handling-form-page" method="post"> <div> <label for="name">姓名:</label> <input type="text" id="name" /> </div> <div> <label for="mail">電子郵箱:</label> <input type="email" id="mail" /> </div> <div> <label for="msg">消息:</label> <textarea id="msg"></textarea> </div> <div class="button"> <button type="submit">發送你的消息</button> </div> </form>
$('#myForm').on('submit', function(e) { e.preventDefault(); // 什麼都不會發生 });
Event.preventDefault能確保表格不會被提交,但他不能阻止來自冒泡階段的submit或點擊事件,其餘兩種方法就是解決這個問題的。post
stopPropagation 保證當前事件再也不進一步冒泡,經過如下代碼示例說明:網站
<div class="container"> <a href="#" class="element">點擊我!</a> </div>
$('.container').on('click', function(e) { console.log('container 被點擊了'); }); $('.element').on('click', function(e) { e.preventDefault(); // 此時連接不會跳轉 console.log('element 被點擊了'); });
此時點擊連接,console會顯示:code
"element 被點擊了" "container 被點擊了"
這時若是添加Event.stopPropagation:orm
$('.container').on('click', function(e) { console.log('container 被點擊了'); }); $('.element').on('click', function(e) { e.preventDefault(); // 此時連接不會跳轉 e.stopPropagation(); // 此時事件冒泡被阻止 console.log('element 被點擊了'); });
再次點擊連接,會看到:htm
"element 被點擊了"
以上兩種方法已經能夠解決咱們在事件處理中90%的問題,接下來介紹一種沒法解決情形。
一樣是使用上面的示例,但此次咱們給<a/>添加2個class,一個是被全部<a/>共享的class: item,另外一個是獨有的class: element,假設這兩個class對當前網站的功能很重要。對象
<div class="container"> <a href="#" class="item element">Click Me!</a> </div>
咱們首先使用以前提到的Event.stopPropagation事件
$('.element').on('click', function(e) { e.preventDefault(); // 此時連接不會跳轉 e.stopPropagation(); // 此時事件冒泡被阻止 console.log('element 被點擊了'); }); $('.item').on('click', function(e) { console.log('item 被點擊了'); });
當咱們點擊<a/>時,將會顯示:
"item 被點擊了" "element 被點擊了"
這個現象會發生是由於item與element在DOM中是被平等對待的,與以前<a/>被點擊而後冒泡到父級div不一樣,此次咱們點擊同時觸發了item與element的事件,此時使用stopPropagation沒法阻止這種事件。
stopImmediatePropagation登場~
他能夠阻止事件冒泡而且阻止相同事件的其餘偵聽器被調用。
$('.element').on('click', function(e) { e.preventDefault(); // 此時連接不會跳轉 e.stopImmediatePropagation(); // item的點擊事件將被阻止 console.log('element 被點擊了'); }); $('.item').on('click', function(e) { console.log('item 被點擊了'); });
這裏咱們要注意的一點是:stopImmediatePropagation的代碼要儘可能放到其餘同級競爭事件代碼的上面,如上面的例子中,爲了使stopImmediatePropagation起做用,咱們將element的事件監聽代碼放到了item以前!
運行最後一例中的代碼,將只會看到:
"element 被點擊了"