問題:
<div class='item' id='outer' onclick="alert('outer')">
<div class='item' id='inner' onclick="alert('inner');">
<div class='item' id='core' onclick="alert('core')">
core!!!!!
</div>
</div>
</div>
1.上面div中,如果單擊core,會執行多少個alert?先后順序是什么?
該問題的答案取決於瀏覽器的對事件處理的機制。對於下圖的結構,當兩個element都綁定了onclick方法時,執行的順序是什么?
----------------------------------- | element1 | | ------------------------- | | |element2 | | | ------------------------- | | | -----------------------------------
- Netscape主張元素1的事件首先發生,這種事件發生順序被稱為捕獲型
- 微軟則保持元素2具有優先權,這種事件順序被稱為冒泡型
- DOM同時支持兩種事件模型:捕獲型事件和冒泡型事件,但是,捕獲型事件先發生。兩種事件流會觸發DOM中的所有對象,從document對象開始,也在document對象結束。
冒泡型:
1.對於某個節點,觸發的一個事件, 會首先執行當前這個dom節點綁定的方法
2.執行完畢后,會冒泡至改節點的父節點,執行相應的函數
3. 重復以上過程,直至Dom的根節點。
對於上文中的例子, 單擊#core,
1.首先觸發alert('core')
2.然后冒泡至#inner節點,觸發alert('inner')
3.最后冒泡至#outer節點,觸發alter('outer')
假設對於#inner,我們未為onclick事件指定方法,那么在第二步,不會有方法執行,但是click的事件,仍會繼續冒泡至最外層的#outer.
捕獲型
事件捕獲的順序剛好與之相反
1.當一個事件發生時,最外層的已綁定該事件的方法會執行
2.然后該事件會下降至他的子節點,觸發相應的方法
3.重復1,2的過程
如何加入一個捕獲型/冒泡型事件
- 參照上文給出的例子,我們直接在html中綁定事件方法, 這個事件就是冒泡型事件
<div class='item' id='outer' onclick="alert('outer')">
- 當采用原生Javascript(非Jquery)方法, 我們使用addEventListener綁定事件 當第三個參數是false的時候, 這個事件就是冒泡型事件(第三個參數的默認值是false).以下兩種寫法等價。
core.addEventListener("click",function(){alert('dddddd')},false);
core.addEventListener("click",function(){alert('dddddd')});
- 我們使用addEventListener綁定事件 當第三個參數是true的時候, 這個事件就是捕獲型事件
core.addEventListener("click",function(){alert('dddddd')},true);
- addEventListe
-
core.addEventListener("click",function(){alert('dddddd')},true);
2. stopPropagation()是停止冒泡事件流。
當我們為一個事件綁定的方法中,添加一句stopPropagation,那么該事件的冒泡過程到此為止,其后的所有節點綁定事件都不執行;
3. 沒有方法去停止捕獲事件流,當然,從功能上看也即沒必要,也不合理。
4.除去addEventListener之外,通過attachEvent也可以綁定事件,attachEvent有哪些參數,執行順序是什么?使用哪種機制?如果同時使用addEventListener和attachEvent,執行順序又是怎樣的?
4.下面是代碼,保存成html文件,看看效果;
<html> <head> <style type="text/css"> .item{ display: table; margin: 100px; } #outer{ width:400px; height:400px; background-color: blue; } #inner{ vertical-align: middle; width:200px; height:200px; background-color: white; } #core{ width:80px; height:80px; background-color: red; text-indent: 10px; line-height: 50px; } </style> </head> <body> <div class='item' id='outer' onclick="alert('outer')"> <div class='item' id='inner' onclick="alert('inner');stopbubble(arguments[0])"> <div class='item' id='core' onclick="alert('core')"> core!!!!! </div> </div> </div> </body> <!--you must write <script> under <body>--> <script type='text/javascript'> var core = document.getElementById('core'); core.addEventListener("click",function(){alert('dddddd')},false); //addEventListener: can add one more event to node "core" function stopbubble(e){ e.stopPropagation();//stop bubble event on this node } </script> </html>
前端效果:
點擊core!!!后:
1.先alert core 因為綁定了dddd,然后會alert dddd;
2.然后冒泡到inner節點后,alert inner,但是同時執行stopbubble(arguments[0])來停止冒泡;
3.停止冒泡后,該node后續節點就不執行了,所以不會alert outer;