原文地址
http://www.ueder.net/2011/01/09/%e9%a1%b5%e9%9d%a2%e6%80%a7%e8%83%bd%e4%bc%98%e5%8c%96%e4%b9%8b%e4%ba%8b%e4%bb%b6%e5%a7%94%e6%89%98/
在現代web追求富媒體應用(RIA)的時代,爲頁面添加事件成爲實現複雜交互行爲的很重要的一部分,然而在javascript中爲頁面添加很多的事件是會造成性能問題的,特別是在IE中,原因可能有很多方面,首先,每個事件都會綁定一個函數function,而每個function都會佔內存,其次,頁面加載時必須事先指定所有頁面事件處理程序,會延遲整個頁面的交互就緒時間。
所謂事件委託就是利用事件的冒泡特性,只需爲所有需要添加事件的子元素的父元素添加一個事件處理程序就可以滿足應用。在DOM標準中,事件支持捕獲及冒泡過程,但IE中只支持冒泡過程,所以我們只需要關注冒泡過程。看下面一段代碼
[隱藏代碼]<ul id="list"> <li id="list1">列表1</li> <li id="list2">列表1</li> <li id="list3">列表1</li> </ul>
在上面這段代碼中,如果我們需要alert出每個li的innerHTML,傳統方法是:
[隱藏代碼]var items = document.getElementById("list").getElementsByTagName("li"); for(var i=0,len=items.length; i<len; i++){ items[i].onclick = function(){ alert(this.innerHTML); }; }
這樣我們就爲頁面添加了三個事件處理程序,如果在更復雜的更多的li元素的頁面,那麼事件處理程序就會更多,會影響到頁面性能,此時我們可以利用事件冒泡優化性能,如下面代碼:
//事件封裝 var EventUtil = { getEvent:function(e){ return e || event; }, getTarget:function(e){ return e.target || e.srcElement; } }; // var list = document.getElementById("list"); list.onclick = function(e){ //獲取事件目標 var evt = EventUtil.getEvent(e); var target = EventUtil.getTarget(evt); // alert(target.innerHTML); };
在這段代碼裏,我們只爲父級元素添加了一個onclick事件,然後根據target獲取事件實際的作用對象,然後執行我們需要的代碼,這樣我們只創建了一個事件處理程序,相較前面的傳統代碼得到了優化。
如果可以的話,也可以考慮爲document添加事件處理程序,以減少在具體元素上添加各種事件,而且document在頁面加載時是最先呈現的,幾乎隨時都可調用到。
另一個與事件有關的影響性能的則是事件的移除,我們在頁面中的DOM操作常常會移除一些頁面元素,而這些元素可能會帶有事件,看下面的例子:
[隱藏代碼]<div id="form"> <button type="submit" id="btn">提交</button> </div> <script type="text/javascript"> var btn = document.getElementById("btn"); btn.onclick = function(){ //執行一些操作... document.getElementById("form").innerHTML = "已提交,等待中..." }; </script>
上面的代碼中點擊按鈕後移除了按鈕,但按鈕上的onclick事件並沒有移除,事件會駐留在內存中,特別是IE不能很好的處理,此時我們可以在事件無用的時候手動移除,如下:
[隱藏代碼]<div id="form"> <button type="submit" id="btn">提交</button> </div> <script type="text/javascript"> var btn = document.getElementById("btn"); btn.onclick = function(){ //執行一些操作... btn.onclick = null; //移除事件處理函數 document.getElementById("form").innerHTML = "已提交,等待中..." }; </script>
所以我們在往頁面添加事件的時候,在不用的時候記得移除,釋放內存。