事件委託

背景

在JS中,添加到頁面上的事件處理程序都會佔用內存,內存佔用的越多性能就越差,且必須事先就指定好全部的事件處理程序而致使的DOM訪問次數的增長會延遲整個頁面的交互就緒時間。特別是對table的td和ul的li的事件處理,若是是給大量子元素添加事件,會佔用大量內存。事件處理程序綁定的越多越影響性能,可是又不能說不綁定事件,因此咱們須要一種方法來減小綁定的事件,使用事件委託。node

原理

在觸發DOM上的某個事件的時候,就會產生一個事件對象event,這個對象中包含着全部與事件有關的信息,其中包括致使事件的元素、事件的類型以及其餘與特定事件相關的信息。避免對特定的每一個節點添加事件監聽器;相反,事件監聽器是被添加到它們的父元素上。事件監聽器會分析從子元素冒泡上來的事件,找到是哪一個子元素的事件。web

使用

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

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

假設,須要觸發每一個li來改變他們的背景顏色,你能夠給每一個獨立的li元素添加事件監聽器。this

window.onload = function(){
    var oUl = document.getElementById("ul");
    var aLi = oUl.getElementsByTagName("li");

    for(var i=0; i<aLi.length; i++){
        aLi[i].onmouseover = function(){
            this.style.background = "red";
        }
        aLi[i].onmouseout = function(){
            this.style.background = "";
        }
    }
}

但有時這些li元素可能會被刪除,可能會有新增,監聽它們的新增或刪除事件將會是一場噩夢,尤爲是當你的監聽事件的代碼放在應用的另外一個地方時。可是,若是你將監聽器安放到它們的父元素上呢?你如何能知道是那個子元素?.net

簡單:當子元素的事件冒泡到父ul元素時,你能夠檢查事件對象的target屬性,捕獲真正節點元素的引用。代理

第一步是給父元素添加事件監聽器。當有事件觸發監聽器時,檢查事件的來源,排除非li子元素事件。若是是一個li元素,咱們就找到了目標!若是不是一個li元素,事件將被忽略。code

window.onload = function(){
    var oUl = document.getElementById("ul");
    var aLi = oUl.getElementsByTagName("li");

/*
這裏要用到事件源:event 對象,事件源,無論在哪一個事件中,只要你操做的那個元素就是事件源。
ie:window.event.srcElement
標準下:event.target
nodeName:找到元素的標籤名
*/
    oUl.onmouseover = function(ev){
        var ev = ev || window.event;
        var target = ev.target || ev.srcElement;
        //alert(target.innerHTML);
        if(target.nodeName.toLowerCase() == "li"){
        target.style.background = "red";
        }
    }
    oUl.onmouseout = function(ev){
        var ev = ev || window.event;
        var target = ev.target || ev.srcElement;
        //alert(target.innerHTML);
        if(target.nodeName.toLowerCase() == "li"){
        target.style.background = "";
        }
    }
}

總結

委託(代理)事件是那些被綁定到父級元素的事件,可是隻有當知足必定匹配條件時纔會被挪。這是靠事件的冒泡機制來實現的。對象

優勢:blog

  • 能夠大量節省內存佔用,減小事件註冊,好比在table上代理全部td的click事件就很是棒seo

  • 能夠實現當新增子對象時無需再次對其綁定事件,對於動態內容部分尤其合適

缺點:

  • 事件代理的應用經常使用應該僅限於上述需求下,若是把全部事件都用代理就可能會出現事件誤判,即本不該用觸發事件的被綁上了事件。當要觸發事件的標籤裏面還有其餘標籤時,不能正常的委託,由於target或srcElemt是裏面的標籤元素。

參考文章
http://www.webhek.com/event-d...
http://blog.csdn.net/jinboker...
http://blog.csdn.net/leo8729/...

相關文章
相關標籤/搜索