JavaScript事件代理和委託

在JavaScript中,常常會碰到要監聽列表中多項li的情形,假設咱們有一個列表以下:html

<ul id="list">
  <li id="item1">item1</li>
  <li id="item2">item2</li>
  <li id="item3">item3</li>
  <li id="item4">item4</li>
</ul>

若是咱們要實現如下功能:當鼠標點擊某一li時,alert輸出該li的內容,咱們一般的寫法是這樣的:node

  • 當列表項比較少時,直接給每一個li添加onclick事件
  • 列表項比較多時,在onload時就給每一個列表項調用監聽

第一種方法比較簡單直接,可是沒有顧及到html與JavaScript的分離,不建議使用,第二種方法的代碼以下:函數

window.onload=function(){
  var ulNode=document.getElementById("list");
  var liNodes=ulNode.childNodes||ulNode.children;
  for(var i=0;i<liNodes.length;i++){
    liNodes[i].addEventListener('click',function(e){
      alert(e.target.innerHTML);
    },false);
  }
}

由上能夠看出來,假如不停的刪除或添加li,則function()也要不停的更改操做,易出錯,所以推薦使用事件代理,在使用事件代理以前,咱們先來了解一下事件階段(event phase):spa

事件階段:

當一個DOM事件被觸發的時候,他並非只在它的起源對象上觸發一次,而是會經歷三個不一樣的階段。簡而言之:事件一開始從文檔的根節點流向目標對象(捕獲階段),而後在目標對向上被觸發(目標階段),以後再回溯到文檔的根節點(冒泡階段)如圖所示(圖片來自W3C):代理

事件捕獲階段(Capture Phase)

事件的第一個階段是捕獲階段。事件從文檔的根節點出發,隨着DOM樹的結構向事件的目標節點流去。途中通過各個層次的DOM節點,並在各節點上觸發捕獲事件,直到到達時間的目標節點。捕獲階段的主要任務是簡歷傳播路徑,在冒泡階段,時間會經過這個路徑回溯到文檔根節點。指針

element.removeEventListener(&ltevent-name>, <callback>, <use-capture>);

咱們經過上面的這個函數來給節點設置監聽,能夠經過將;設置成true來爲事件的捕獲階段添加監聽回調函數。在實際應用中,咱們並無太多使用捕獲階段監聽的用例,可是經過在捕獲階段對事件的處理,咱們能夠阻止相似click事件在某個特定元素上被觸發。code

var form=document.querySeletor('form');
form.addEventListener('click',function(e){
  e.stopPropagation();
  },true);

若是你對這種用法不是很瞭解的話,最好仍是將設置爲false或者undefined,從而在冒泡階段對事件進行監聽。orm

目標階段(Target Phase)

當事件到達目標節點時,事件就進入了目標階段。事件在目標節點上被觸發,而後逆向迴流,知道傳播到最外層的文檔節點。cdn

對於多層嵌套的節點,鼠標和指針事件常常會被定位到最裏層的元素上。假設,你在一個div元素上設置了click的監聽函數,而用戶點擊在了這個div元素內部的p元素上,那麼p元素就是這個時間的目標元素。事件冒泡讓咱們能夠在這個div或者更上層的元素上監聽click事件,而且時間傳播過程當中觸發回調函數。htm

冒泡階段(Bubble Phase)

事件在目標事件上觸發後,並不在這個元素上終止。它會隨着DOM樹一層層向上冒泡,直到到達最外層的根節點。也就是說,同一事件會一次在目標節點的父節點,父節點的父節點...直到最外層的節點上觸發。

絕大多數事件是會冒泡的,但並不是全部的。具體可見:規範說明

由上咱們能夠想到,可使用事件代理來實現對每個li的監聽。代碼以下:

window.onload=function(){
  var ulNode=document.getElementById("list");
  ulNode.addEventListener('click',function(e){
       if(e.target&&e.target.nodeName.toUpperCase()=="LI"){/*判斷目標事件是否爲li*/
         alert(e.target.innerHTML);
       }
     },false);
  
};
相關文章
相關標籤/搜索