天天看點

JS中的事件委托和移除事件處理程式

1.什麼是事件委托?

對“事件處理程式過多”的問題的解決方案就是事件委托。事件委托利用事件冒泡,隻指定一個事件處理程式,就可以管理某一類型的所有事件。例如,click事件會一直冒泡到documeng層次,也就是說我們可以為整個頁面指定一個onclick事件處理程式,而不必給每一個可單擊的元素分别添加事件處理程式。如下代碼:

//html
<ul id="myLinks">
  <li id="goSomewhere">GO Somewhere</li>
  <li id="doSomething">Do something</li>
  <li id="sayhi"> Say Hi</li>

</ul>
//js
var item1=document.getElementById("goSomewhere");
var item2=document.getElementById("doSomething");
var item3= document.getElementById("sayhi");

item1.addEventListener("click",function(){
    location.href="http://www.hao123.com";
    },false);
item2.addEventListener("click",function(){
    document.title="事件委托";
    },false);
item3.addEventListener("click",function(){
    alert("Hi");
    },false);
           

這是傳統的方式為每個li元素添加事件處理程式,但是如果在一個複雜的web應用程式中,對所有可點選的元素都采用這種方式,那麼結果就會有數不清的代碼用于添加事件處理程式。此時可以使用事件委托技術解決這個問題,隻需要在DOM樹種盡量高的層次上添加一個事件處理程式,如下:

var list=document.getElementById("myLinks");
list.addEventListener("click",function(event){
    switch(event.target.id){
        case "goSomewhere":
           location.href="http://www.hao123.com";
           break;

        case "doSomething":
           document.title="事件委托";
           break;

        case "sayhi":
           alert("Hi");
           break;
        }
    },false)
           

在這段代碼中,我們使用事件委托隻為ul元素添加了一個onclick事件處理程式,由于所有可單擊的元素都是它的子元素,是以都會冒泡到父元素,最終被父元素上的事件處理程式解決。這種技術的好處在于占用記憶體更少,所耗費的時間更少。是以用到按鈕的事件都可以用事件委托技術。

2.移除事件處理程式

記憶體中留有那些過時不用的“空事件處理程式”,是造成web應用程式記憶體和性能問題的主要原因。是以在不需要的時候事件處理程式,就可以移除它。

例如當代有事件處理程式的元素被innerHTML删除了,那麼原來添加到元素的事件處理程式極有可能無法被當作垃圾回收。

<div id="mydiv">
<input type="button" id="mybtn" />
</div>

var btn=document.getElementById("mybtn");
btn.onclick=function(event){
    document.getElementById("mydiv").innerHTML="變化了";
    }
           

當按鈕被移除時,他還帶着一個事件處理程式呢,在div元素上設定innerHTML可以把按鈕一周,但事件處理程式仍然與按鈕保持引用關系。是以當你知道哪些元素被移除,最好手工移除對應事件處理程式。

var btn=document.getElementById("mybtn");
btn.onclick=function(event){

    btn.onclick=null;
    document.getElementById("mydiv").innerHTML="變化了";
    }
           

在此我們在設定innerHTML屬性之前,先移除按鈕的事件處理程式。這樣就確定記憶體可以被再次利用。