1. 程式人生 > >淺談JavaScript的事件(事件委托)

淺談JavaScript的事件(事件委托)

沒有 str 方法 比較 獲取 ack 使用 點擊 通過

  事件處理程序為Web程序提供了系統交互,但是如果頁面中的事件處理程序太多,則會影響頁面的性能。每個函數都是對象,都會占用內存,內存中對象越多,性能越差。需要事先為DOM對象指定事件處理程序,導致訪問DOM的次數增多,會延遲整個頁面的交互就緒時間。

  • 事件委托

  對事件處理程序過多的解決方案是使用事件委托。事件委托利用了事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件。比如click事件會一直冒泡到document,也就是說我們只需為整個頁面指定一個onclick事件處理程序,而不必為每個需要點擊事件的元素單獨添加。

1 <ul id="ul1">
2             <
li id="li1">111</li> 3 <li id="li2">222</li> 4 </ul>

  例如上面的代碼,如果我們采用常規手段來添加事件處理程序,我們需要為每個li都添加事件。但是如果采用冒泡,我們只需要指定一個事件處理程序,並且能夠實現同樣的功能。

 1 var oUl = document.getElementById("ul1"); 
 2             EventUtil.addEvent(oUl, "click", function(ev) {    
 3                 var ev = EventUtil.getEvent(ev);    
4 var target = EventUtil.getTarget(ev);     5 if(target.id == ‘li1‘) {        6 console.log("1");    7 } 8 else if(target.id=="li2"){ 9 console.log("2"); 10 }   11 });

  上面的代碼中,通過事件冒泡為ul1指定了事件處理程序,在我們單擊li的時候通過事件冒泡也會觸發該事件,並且能夠通過target來獲取當前單擊的元素對象。通過元素id,為每個元素執行不同的if語句。

並不是所有的事件都適合使用事件委托,比較適用的事件是:mouseup、mousedown、click、keyup、keydown和keypress。雖然mouseover和mouseout也支持事件冒泡,但是如果使用事件委托則處理就比較麻煩,而且需要計算鼠標的位置以及元素的位置(當鼠標從一個元素移到其子節點,或者移出元素都會觸發mouseout事件)。

 1 var oUl = document.getElementById("ul1"); 
 2             EventUtil.addEvent(oUl, "mouseout", function(ev) {    
 3                 var ev = EventUtil.getEvent(ev);    
 4                 var target = EventUtil.getTarget(ev);    
 5                 if(target.id == ‘li1‘) {       
 6                     console.log("1");   
 7                 }
 8                 else if(target.id=="li2"){
 9                     console.log("2");
10                 }  
11             });

  比如上面的代碼,當鼠標移到li元素的時候會觸發mouseout,鼠標移出ul元素的時候也會觸發mouseout事件。

  • 移除事件處理程序

  前文已經講過事件的添加以及事件的移除。對於頁面的事件處理程序太多,會影響頁面的性能,除了使用事件委托之外,還可以將一些事件移除。內存中留有的一些過時的用不到的事件處理程序也是造成Web頁面和內存性能的主要問題。

  我們移除頁面中的元素時候,可以通過removeChild和replaceChild方法,但有時候也會使用innerHTML來替換元素。如果某個元素有事件處理程序,通過innerHTML來替換,則事件處理程序依然存在,那麽該事件處理程序已經使用不到,但是它也無法被回收,會一直占用內存空間。

  

1 <div id="firstdiv">
2             <input type="button" id="btnadd" value="添加" />
3         </div>
1 EventUtil.addEvent(document.getElementById("btnadd"),"click",function(event){
2                 document.getElementById("firstdiv").innerHTML="processing";
3             });

  上面的代碼中為btnadd元素綁定了單擊事件,單擊的時候通過innerHTML移除了該元素,但是元素的事件處理程序並沒有移除,依然留在內存中。

  

1 var callback =function(event){
2                 EventUtil.removeEvent(document.getElementById("btnadd"),"click",callback);
3                 document.getElementById("firstdiv").innerHTML="processing";
4             }
5             EventUtil.addEvent(document.getElementById("btnadd"),"click",callback);

  上面的代碼,我們在元素移除之前,手動移除了元素的事件處理程序。這樣確保內存中也移除了該事件處理程序,而從DOM中移除按鈕也非常徹底。

淺談JavaScript的事件(事件委托)