個人筆記,如有錯誤,望指出。
事件冒泡,舉個列子:
<li> <a href='http://www.baidu.com'>點擊a</a> </li> <script> $('li').click(function () { alert('點擊了li'); }); $('a').click(function () { alert('點擊了a'); }); </script>
當你點擊a的時候,會先彈出‘點擊了a’,再彈出‘點擊了li’,最后跳轉到百度。簡單理解就是先執行子元素的事件,再執行父元素的事件,跟事件捕獲相反。
有些時候,我們不希望發生父元素的事件,只發生子元素的事件,這時候就需要阻止事件冒泡。分析一下事件冒泡,順便分析一下阻止瀏覽器默認行為的一些方法:
1、event.stopPropagation();(阻止冒泡)
2、event.cancelBubble = true;(阻止冒泡)
3、event.preventDefault();(阻止瀏覽器默認行為)
4、return false;(有很多行為)
一、event.stopPropagation();
<script> $('li').click(function () { alert('點擊了li'); }); $('a').click(function (event) { alert('點擊了a'); event.stopPropagation(); }); </script>
完美阻止了li元素的冒泡,並且不會影響a的事件。效果是:先彈出‘點擊了a’,然后跳轉百度
注:之前看到說是不兼容IE8及一下,親測IE6以上沒問題,如有錯,望指出。
二、event.cancelBubble = true;
<script> $('li').click(function () { alert('點擊了li'); }); $('a').click(function () { alert('點擊了a'); console.log(event); event.cancelBubble = true; }); </script>
使用cancelBubble需要注意:
event事件是窗口的MouseEvent,此處console.log打印的是:MouseEvent {isTrusted: true, screenX: 55, screenY: 90, clientX: 55, clientY: 29…}
。效果跟上面的是一樣:先彈出‘點擊了a’,然后跳轉百度。剛剛測的時候,好像兼容性也還好。
三、event.preventDefault();
<script> $('li').click(function () { alert('點擊了li'); }); $('a').click(function (event) { alert('點擊了a'); event.preventDefault(); }); </script>
執行后的效果:先彈出‘點擊了a’,再彈出‘點擊了li’,但是,不執行跳轉!不執行跳轉!不執行跳轉!
其實,default英文意思是默認的,想想不難理解,頁面中,除了執行監聽事件還會觸發瀏覽器默認動作; 執行監聽事件在前, 觸發瀏覽器默認動作在后。
preventDefault並不是阻止事件冒泡,只是阻止瀏覽器的默認動作。而stopPropagation跟cancelBubble只是阻止事件冒泡,並沒有阻止
瀏覽器的默認動作。當我們希望阻止事件冒泡的同時,也阻止瀏覽器的默認動作時,就可以2者都一起使用,如下代碼:
<script> $('li').click(function () { alert('點擊了li'); }); $('a').click(function (event) { alert('點擊了a'); console.log(event); event.stopPropagation(); event.preventDefault(); }); </script>
效果是:只彈出‘點擊了a’,並不跳轉百度鏈接,也不彈出‘點擊了li’。
四、最后的一個return false;
<script> $('li').click(function () { alert('點擊了li'); }); $('a').click(function () { alert('點擊了a'); return false; }); </script>
執行效果:只彈出‘點擊了a’,並不跳轉百度鏈接,也不彈出‘點擊了li’。跟(stopPropagation+preventDefault)是一個效果。
退出執行, return false
之后的所有觸發事件和動作都不會被執行. 有時候 return false
可以用來替代stopPropagation()
和
preventDefault()
, 比如上面的例子。
值得注意的一點:有人認為 return false
= stopPropagation()
+ preventDefault()
,其實是錯的。 return false
不但阻止事件,
還可以返回對象, 跳出循環等... 方便地一刀切而不夠靈活, 濫用易出錯。
貼一下本博客的html的代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件冒泡</title> </head> <body> <ul> <li> <a href='#'>點擊a</a> </li> </ul> <script src="jquery-1.11.3.min.js"></script> <script> $('li').click(function () { alert('點擊了li'); }); $('a').click(function (event) { alert('點擊了a'); console.log(event); event.stopPropagation(); // event.cancelBubble = true; event.preventDefault(); // return false; }); </script> </body> </html>
補充:謝謝博友指出,對於return false;我說明的比較少,其實return false並不是事件冒泡,本文講的是跟事件冒泡有關的內容,return false在某種情況下也能實現。
因為return false不但阻止了事件,也阻止了瀏覽器的默認行為,就像一個終止符,也常常用它來阻止提交表單或者繼續執行下面的代碼,並且只在當前函數下
有用,return false執行了以下行為:
1、執行event.preventDefault(); 阻止瀏覽器的默認行為;
2、event.stopPropagation(); 阻止冒泡行為;
3、停止回調函數執行並立即返回。
寫文章之前,我看到這樣一句話:“cancelBubble用於ie的阻止冒泡事件,event.stopPropagation()用於firefox和chrome等其他瀏覽器。”。我不
知道現在還是不是這樣子,測試的時候兼容是好的,所以就沒有說明這一點。當然,為了保險起見,博友幫我封了一個函數,感謝!文中不對之處還望指出,多多學習。
//阻止冒泡事件 function stopBubble(e){ if(e && e.stopPropagation){ // 非IE瀏覽器 e.stopPropagation(); }else{ //IE瀏覽器 window.event.cancelBubble=true; } }
同理,如果想阻止瀏覽器的默認事件
//阻止瀏覽器默認行為 function stopDefault(e){ //標准瀏覽器 if(e && e.preventDefault){ e.preventDefault(); } //個別IE else{ window.event.returnValue=fale; return false; } }