「DOM2級事件」規定的事件流包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。下面這個圖可以很形象的解釋(理解捕獲和冒泡必不可少的圖)javascript
按照圖咱們編寫了代碼去驗證下,html
<div id="parent"> <div id="child"> child </div> </div> <script type="text/javascript"> var p = document.getElementById('parent'), c = document.getElementById('child'); p.addEventListener('click', function (e) { console.log('父節點捕獲') }, true); c.addEventListener('click', function (e) { console.log('子節點捕獲') }, true); c.addEventListener('click', function (e) { console.log('子節點冒泡'); }, false); p.addEventListener('click', function (e) { console.log('父節點冒泡') }, false); </script>
結果一目瞭然java
可是這裏有個問題,也是原來阿里的面試題目,jquery
這個在參考小鬍子哥的寫js事件機制的博客中瞭解到,順序是和綁定順序有關係的,那咱們來試一下,面試
<div id="parent" style="height: 300px; background-color: #ccc;"> <div id="child"> child </div> <p>other child</p> </div> <script type="text/javascript"> var p = document.getElementById('parent'), c = document.getElementById('child'); p.addEventListener('click', function (e) { console.log('父節點冒泡') }, false); c.addEventListener('click', function (e) { console.log('子節點冒泡'); }, false); c.addEventListener('click', function (e) { console.log('子節點捕獲') }, true); p.addEventListener('click', function (e) { console.log('父節點捕獲') }, true); </script>
當點擊1時dom
當點擊2時ide
當點擊3時spa
咱們發現1和3的狀況下是先冒泡後捕獲的,代碼中我將冒泡的的綁定事件寫到捕獲前面了,形成了這樣的效果,代理
那第二種爲何順序是先捕獲後冒泡的呢,是由於事件目的地點 other child沒有綁定事件。code
有捕獲和冒泡就有相應的阻止,stopPropagation這個應該是阻止事件的下一步傳播,stopImmediatePropagation這個方法能把綁定在這個元素上的事件都能阻止掉,能夠了解下。
另附,易混淆的,
對「事件處理程序過多」問題的解決方案就是事件委託,事件委託利用了事件冒泡,只指定一個事件處理程序,就能管理這一類型的全部事件。
好比對ul下的li綁定事件,通常是遍歷li,給每一個li綁定事件,這個有兩個問題,1,若是是新加的li,咱們須要從新綁定。2,若是li有不少,那佔用內存會不少。
那咱們這個時候就能夠用事件委託了,委託在詞典中解釋,將本身的事務囑託他人代爲處理。那就是事件我不放到要處理的dom上面,也就是利用冒泡的原理,將事件綁定到父級上面。再按照每一個觸發事件的event對象找到target,說到這,又要說兼容問題了,w3c的標準下的,event.target便可,IE的確是event.srcElement。到這我想你們應該會想到一個神器,jQuery了,對的,他裏面的綁定事件都是兼容的,都是封裝好的,那他又是怎麼處理的呢,好吧,要去解讀源碼了。