javascript事件機制瞭解與深刻

1、事件的捕獲與冒泡

    「DOM2級事件」規定的事件流包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。下面這個圖可以很形象的解釋(理解捕獲和冒泡必不可少的圖)javascript

59e2d17f-ae58-4591-bd37-93ebe7f0b5ee

按照圖咱們編寫了代碼去驗證下,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>
View Code

結果一目瞭然java

992dead0-0481-4660-8a6d-dde631cf236d

可是這裏有個問題,也是原來阿里的面試題目,jquery

如果一個dom上綁定了兩次事件,一個捕獲,一個冒泡的,事件執行順序是什麼呢,

這個在參考小鬍子哥的寫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>
View Code

 

60467b7e-cffe-4953-9d80-3e7c1a80a878

當點擊1時dom

6135b410-6f49-4ef1-a71f-f7a78a96043a

當點擊2時ide

4aa11a0c-8119-4245-bb54-6d9840f16e18

當點擊3時spa

491becc5-6e53-449b-ae3b-b8b5a376d43c

咱們發現1和3的狀況下是先冒泡後捕獲的,代碼中我將冒泡的的綁定事件寫到捕獲前面了,形成了這樣的效果,代理

事件目的地節點既綁定了冒泡事件也綁定了捕獲事件,此時的執行順序按照綁定的前後順序執行

那第二種爲何順序是先捕獲後冒泡的呢,是由於事件目的地點 other child沒有綁定事件。code

有捕獲和冒泡就有相應的阻止,stopPropagation這個應該是阻止事件的下一步傳播,stopImmediatePropagation這個方法能把綁定在這個元素上的事件都能阻止掉,能夠了解下。

另附,易混淆的,

event.prevetDefault() => 默認事件
event.stopPropogation() => 事件捕獲、事件冒泡,事件代理
return false => jquery內部就是調用了上面兩個實現的。

二,事件委託機制

對「事件處理程序過多」問題的解決方案就是事件委託,事件委託利用了事件冒泡,只指定一個事件處理程序,就能管理這一類型的全部事件。

好比對ul下的li綁定事件,通常是遍歷li,給每一個li綁定事件,這個有兩個問題,1,若是是新加的li,咱們須要從新綁定。2,若是li有不少,那佔用內存會不少。

那咱們這個時候就能夠用事件委託了,委託在詞典中解釋,將本身的事務囑託他人代爲處理。那就是事件我不放到要處理的dom上面,也就是利用冒泡的原理,將事件綁定到父級上面。再按照每一個觸發事件的event對象找到target,說到這,又要說兼容問題了,w3c的標準下的,event.target便可,IE的確是event.srcElement。到這我想你們應該會想到一個神器,jQuery了,對的,他裏面的綁定事件都是兼容的,都是封裝好的,那他又是怎麼處理的呢,好吧,要去解讀源碼了。

參考博客:

[解惑]JavaScript事件機制

【探討】javascript事件機制底層實現原理

相關文章
相關標籤/搜索