一、事件捕獲
捕獲型事件(event capturing):事件從最不精確的對象(document 對象)開始觸發,而後到最精確(也能夠在窗口級別捕獲事件,不過必須由開發人員特別指定)javascript
二、事件冒泡
冒泡型事件:事件按照從最特定的事件目標到最不特定的事件目標(document對象)的順序觸發。html
三、捕獲和冒泡過程圖java
事件捕獲和事件冒泡屬於兩個相反的過程,這裏能夠有一個我感受十分恰當的比喻,當你把一個能夠漂浮在水面上的物品,使勁向水裏砸下去,它會首先有一個降低的過程,這個過程就能夠理解爲從最頂層向事件發生的最具體元素(目標點)的捕獲過程;以後因爲浮力大於物體自身的重力,物體會在到達最低點( 最具體元素)以後漂浮到水面上,這個過程相對於事件捕獲是一個回溯的過程,即事件冒泡。
好了,對於事件捕獲和事件冒泡有了一個概念上的理解,那咱們就能夠開始考慮實際的編碼過程當中的實際應用了。先貼上本文所須要的代碼node
<!DOCTYPE html> <html> <head> <title>event</title> </head> <body> <div id="obj1"> welcome <h5 id="obj2">hello</h5> <h5 id="obj3">world</h5> </div> <script type="text/javascript"> var obj1=document.getElementById('obj1'); var obj2=document.getElementById('obj2'); obj1.addEventListener('click',function(){ alert('hello'); },false); obj2.addEventListener('click',function(){ alert('world'); }) </script> </body> </html>
如上所示,這是一個十分簡單地文檔結構:document > html > body > div > h5
而且分別在obj1,obj2上綁定了一個點擊事件,因爲addEventListener的第三個參數爲false,因此頁面是在冒泡階段處理綁定事件。此時整個頁面能夠有三種行爲出現性能
點擊文字welcome時,彈出hello。
此時就只觸發了綁定在obj1上的點擊事件。具體冒泡實現過程以下:welcome 屬於文本節點,點擊後,開始從文本節點查找,當前文本節點沒有綁定點擊事件,繼續向上找,找到父級(id爲obj1的div),有綁定的點擊事件,執行,再向上找,body,沒有綁定點擊事件,再到html,document,都沒再有綁定的點擊事件,好,整個冒泡過程結束。
點擊文字hello時,先彈出world,再彈出hello。
具體冒泡的過程以下圖所示編碼
3. 點擊world時,彈出hello。
具體冒泡過程和第二種狀況相似,以下圖spa
理解了以上的內容,咱們能夠接着來討論事件代理機制。
好比上面的代碼,咱們想要在點擊每一個h5標籤時,彈出對應的innerHTML 。常規作法是遍歷每一個h5,而後在每一個h5上綁定一個點擊事件,這種作法在h5較少的時候可使用,但若是有一萬個h5,那就會致使性能下降。這時就須要事件代理出場了。
先貼代碼.net
obj1.addEventListener('click',function(e){ var e=e||window.event; if(e.target.nodeName.toLowerCase()=='h5'){ alert(e.target.innerHTML); } },false);
因爲事件冒泡機制,點擊了h5後會冒泡到div,此時就會觸發綁定在div上的點擊事件,再利用target找到事件實際發生的元素,就能夠達到預期的效果。代理
兩種方式來阻止事件冒泡。
方式一:code
$("#div1").mousedown(function(event){ event.stopPropagation(); });
方式二:return false;
$("#div1").mousedown(function(event){
return false;
});
可是這兩種方式是有區別的。return false 不只阻止了事件往上冒泡,並且阻止了事件自己。event.stopPropagation() 則只阻止事件往上冒泡,不阻止事件自己。
————————————————
原文連接:https://blog.csdn.net/chenjuan1993/article/details/81347590
這篇文章也很不錯,可借鑑https://www.jianshu.com/p/d3e9b653fa95