天天看點

前端學習(52)~事件委托

事件委托

事件委托,通俗地來講,就是把一個元素響應事件(click、keydown......)的函數委托到另一個元素。

比如說有一個清單 ul,清單之中有大量的清單項

<a>

标簽:

<ul id="parent-list">
    <li><a href="javascript:;" class="my_link">超連結一</a></li>
    <li><a href="javascript:;" class="my_link">超連結二</a></li>
    <li><a href="javascript:;" class="my_link">超連結三</a></li>
</ul>           

複制

當我們的滑鼠移到

<a>

标簽上的時候,需要擷取此

<a>

的相關資訊并飄出懸浮窗以顯示詳細資訊,或者當某個

<a>

被點選的時候需要觸發相應的處理事件。我們通常的寫法,是為每個

<a>

都綁定類似onMouseOver或者onClick之類的事件監聽:

window.onload = function(){
        var parentNode = document.getElementById("parent-list");
        var aNodes = parentNode.getElementByTagName("a");
        for(var i=0, l = aNodes.length; i < l; i++){

            aNodes[i].onclick = function() {
                console.log('我是超連結 a 的單擊相應函數');
            }
        }
    }           

複制

但是,上面的做法過于消耗記憶體和性能。我們希望,隻綁定一次事件,即可應用到多個元素上,即使元素是後來添加的。

是以,比較好的方法就是把這個點選事件綁定到他的父層,也就是

ul

上,然後在執行事件函數的時候再去比對判斷目标元素。如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript">
            window.onload = function() {

                // 擷取父節點,并為它綁定click單擊事件。 false 表示事件在冒泡階段觸發(預設)
                document.getElementById('parent-list').addEventListener('click', function(event) {
                    event = event || window.event;

                    // e.target 表示:觸發事件的對象
                    //如果觸發事件的對象是我們期望的元素,則執行否則不執行
                    if (event.target && event.target.className == 'link') {
                    // 或者寫成 if (event.target && event.target.nodeName.toUpperCase() == 'A') {
                        console.log('我是ul的單擊響應函數');
                    }
                }, false);
            };
        </script>
    </head>
    <body>
        <ul id="parent-list" style="background-color: #bfa;">
            <li>
                <p>我是p元素</p>
            </li>
            <li><a href="javascript:;" class="link">超連結一</a></li>
            <li><a href="javascript:;" class="link">超連結二</a></li>
            <li><a href="javascript:;" class="link">超連結三</a></li>
        </ul>
    </body>           

複制

上方代碼,為父節點注冊 click 事件,當子節點被點選的時候,click事件會從子節點開始向父節點冒泡。父節點捕獲到事件之後,開始執行方法體裡的内容:通過判斷 event.target 拿到了被點選的子節點

<a>

。進而可以擷取到相應的資訊,并作處理。

換而言之,參數為false,說明事件是在冒泡階段觸發(子元素向父元素傳遞事件)。而父節點注冊了事件函數,子節點沒有注冊事件函數,此時,會在父節點中執行函數體裡的代碼。

總結:事件委托是利用了冒泡機制,減少了事件綁定的次數,減少記憶體消耗,提高性能。