在JavaScript中,添加到頁面上的事件處理程序的數量直接關系到頁面的整體運行性能:
首先,每個函數都是對象,都會占用內存;內存中的對象越多,性能就越差。
其次,必須事先指定所有事件處理程序,會導致DOM訪問次數增加,會延遲整個頁面的交互就緒時間。
事件委托就是事件目標本身不處理事件,而是把處理任務委托給其父元素或祖先元素。事件委托利用了事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件。
事件委托解決了"事件處理程序過多"的問題。
假定現在有個ul無序列表(id為items),其中li(id為item+序號)代表每個項,當點擊項時需彈窗顯示項的基本信息。
采用事件綁定li的方法(addHandler是跨浏覽器的添加事件處理程序函數,具體實現見JavaScript事件章節):
var item1 = document.getElementById('item1'); var item2 = document.getElementById('item2'); var item3 = document.getElementById('item3'); EventUtil.addHandler(item1, "click", function(){ alert("I am item1!"); }); EventUtil.addHandler(item2, "click", function(){ alert("I am item2!"); }); EventUtil.addHandler(item3, "click", function(){ alert("I am item3!"); });
使用事件委托,只需在DOM樹種盡量最高的層次添加一個事件處理程序。
var items = document.getElementById('items'); EventUtil.addHandler(items, "click", function(event){ var event = EventUtil.getEvent(event); var target = EventUtil.getTarget(event); alert("I am " + target.id); });
這裡,通過事件委托只為ul元素添加了一個onclick的事件處理程序。由於所有li都是這個ul的子節點,而且它們的事件會冒泡,所以單擊事件最終會被這個函數處理。
對比普通的事件綁定代碼和使用事件委托後的代碼,會發現使用事件委托後消耗更小:只獲取了一個DOM節點,只添加了一個事件處理程序,占用的內存更小。
所有用到按鈕的事件(多數鼠標事件和鍵盤事件)都適合采用委托的技術。
減少浏覽器代碼和支持頁面交互的JavaScript代碼之間的連接,通常有兩種方法:
1.使用事件委托技術,限制建立的連接數量;
2.在不需要的時候,移除事件處理程序。
如果沒有很好地移除事件處理程序,會導致"空事件處理程序",進而也會影響程序內存和性能,造成空事件處理程序的原因:
1.從文檔中移除了帶有事件處理程序的元素(removeChild(),replaceChild());
2.帶有事件處理程序的元素被innerHTML刪除了。解決辦法在innerHTML操作前通過給事件賦值null移除事件處理程序。
3.頁面卸載的時候(IE8-),如果在頁面被卸載前沒有清理干淨事件處理程序,那麼它們就會滯留在內存。解決辦法通過onunload事件處理程序移除所有事件處理程序。