事件委託原理

事件委託(event delegation)。node

事件委託技術能讓你避免對特定的每一個節點添加事件監聽器;相反,事件監聽器是被添加到它們的父元素上。事件監聽器會分析從子元素冒泡上來的事件,找到是哪一個子元素的事件。基本概念很是簡單,但仍有不少人不理解事件委託的工做原理。這裏我將要解釋事件委託是如何工做的,並提供幾個純JavaScript的基本事件委託的例子。post

假定咱們有一個UL元素,它有幾個子元素:spa

<ul id="parent-list">
        <li id="post-1">Item 1</li>
        <li id="post-2">Item 2</li>
        <li id="post-3">Item 3</li>
        <li id="post-4">Item 4</li>
        <li id="post-5">Item 5</li>
        <li id="post-6">Item 6</li>
    </ul>

咱們還假設,當每一個子元素被點擊時,將會有各自不一樣的事件發生。你能夠給每一個獨立的li元素添加事件監聽器,但有時這些li元素可能會被刪除,可能會有新增,監聽它們的新增或刪除事件將會是一場噩夢,尤爲是當你的監聽事件的代碼放在應用的另外一個地方時。可是,若是你將監聽器安放到它們的父元素上呢?你如何能知道是那個子元素被點擊了?code

簡單:當子元素的事件冒泡到父ul元素時,你能夠檢查事件對象的target屬性,捕獲真正被點擊的節點元素的引用。下面是一段很簡單的JavaScript代碼,演示了事件委託的過程:對象

// 找到父元素,添加監聽器...
    document.getElementById("parent-list").addEventListener("click",function(e) {
        // e.target是被點擊的元素!
        // 若是被點擊的是li元素
        if(e.target && e.target.nodeName == "LI") {
            // 找到目標,輸出ID!
            console.log("List item ",e.target.id.replace("post-",'')," was clicked!");
        }
    });

第一步是給父元素添加事件監聽器。當有事件觸發監聽器時,檢查事件的來源,排除非li子元素事件。若是是一個li元素,咱們就找到了目標!若是不是一個li元素,事件將被忽略。這個例子很是簡單,UL和li是標準的父子搭配。讓咱們試驗一些差別比較大的元素搭配。假設咱們有一個父元素div,裏面有不少子元素,但咱們關心的是裏面的一個帶有」classA」 CSS類的A標記:事件

// 得到父元素DIV, 添加監聽器...
    document.getElementById("myDiv").addEventListener("click",function(e) {
        // e.target是被點擊的元素
        if(e.target && e.target.nodeName == "A") {
            // 得到CSS類名
            var classes = e.target.className.split(" ");
                // 搜索匹配!
                if(classes) {
                    // For every CSS class the element has...
                    for(var x = 0; x < classes.length; x++) {
                        // If it has the CSS class we want...
                        if(classes[x] == "classA") {
                            // Bingo!
                            console.log("Anchor element clicked!");
                            // Now do something here....
                        }
                    }
                }
        }
    });

上面這個例子中不只比較了標籤名,並且比較了CSS類名。雖然稍微複雜了一點,但仍是很具表明性的。好比,若是某個A標記裏有一個span標記,則這個span將會成爲target元素。這個時候,咱們須要上溯DOM樹結構,找到裏面是否有一個 A.classA 的元素ip

相關文章
相關標籤/搜索