欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript的事件代理和委托實(shí)例分析

 更新時(shí)間:2015年03月25日 11:55:35   投稿:hebedich  
在javasript中delegate這個(gè)詞經(jīng)常出現(xiàn),看字面的意思,代理、委托。在各種框架中,也經(jīng)常能看到delegate相關(guān)的接口。這些接口又有什么特殊的用法呢?這篇文章就主要通過(guò)實(shí)例介紹一下javascript delegate的用法和原理。

在JavaScript中,經(jīng)常會(huì)碰到要監(jiān)聽(tīng)列表中多項(xiàng)li的情形,假設(shè)我們有一個(gè)列表如下:

復(fù)制代碼 代碼如下:

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

如果我們要實(shí)現(xiàn)以下功能:當(dāng)鼠標(biāo)點(diǎn)擊某一li時(shí),alert輸出該li的內(nèi)容,我們通常的寫(xiě)法是這樣的:

當(dāng)列表項(xiàng)比較少時(shí),直接給每個(gè)li添加onclick事件
列表項(xiàng)比較多時(shí),在onload時(shí)就給每個(gè)列表項(xiàng)調(diào)用監(jiān)聽(tīng)
第一種方法比較簡(jiǎn)單直接,但是沒(méi)有顧及到html與JavaScript的分離,不建議使用,第二種方法的代碼如下:

復(fù)制代碼 代碼如下:

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);
  }
}

由上可以看出來(lái),假如不停的刪除或添加li,則function()也要不停的更改操作,易出錯(cuò),因此推薦使用事件代理,在使用事件代理之前,我們先來(lái)了解一下事件階段(event phase):

事件階段:

當(dāng)一個(gè)DOM事件被觸發(fā)的時(shí)候,他并不是只在它的起源對(duì)象上觸發(fā)一次,而是會(huì)經(jīng)歷三個(gè)不同的階段。簡(jiǎn)而言之:事件一開(kāi)始從文檔的根節(jié)點(diǎn)流向目標(biāo)對(duì)象(捕獲階段),然后在目標(biāo)對(duì)向上被觸發(fā)(目標(biāo)階段),之后再回溯到文檔的根節(jié)點(diǎn)(冒泡階段)如圖所示(圖片來(lái)自W3C):

事件捕獲階段(Capture Phase)

事件的第一個(gè)階段是捕獲階段。事件從文檔的根節(jié)點(diǎn)出發(fā),隨著DOM樹(shù)的結(jié)構(gòu)向事件的目標(biāo)節(jié)點(diǎn)流去。途中經(jīng)過(guò)各個(gè)層次的DOM節(jié)點(diǎn),并在各節(jié)點(diǎn)上觸發(fā)捕獲事件,直到到達(dá)時(shí)間的目標(biāo)節(jié)點(diǎn)。捕獲階段的主要任務(wù)是簡(jiǎn)歷傳播路徑,在冒泡階段,時(shí)間會(huì)通過(guò)這個(gè)路徑回溯到文檔根節(jié)點(diǎn)。

復(fù)制代碼 代碼如下:

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

我們通過(guò)上面的這個(gè)函數(shù)來(lái)給節(jié)點(diǎn)設(shè)置監(jiān)聽(tīng),可以通過(guò)將;設(shè)置成true來(lái)為事件的捕獲階段添加監(jiān)聽(tīng)回調(diào)函數(shù)。在實(shí)際應(yīng)用中,我們并沒(méi)有太多使用捕獲階段監(jiān)聽(tīng)的用例,但是通過(guò)在捕獲階段對(duì)事件的處理,我們可以阻止類(lèi)似click事件在某個(gè)特定元素上被觸發(fā)。

復(fù)制代碼 代碼如下:

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

如果你對(duì)這種用法不是很了解的話,最好還是將設(shè)置為false或者undefined,從而在冒泡階段對(duì)事件進(jìn)行監(jiān)聽(tīng)。

目標(biāo)階段(Target Phase)

當(dāng)事件到達(dá)目標(biāo)節(jié)點(diǎn)時(shí),事件就進(jìn)入了目標(biāo)階段。事件在目標(biāo)節(jié)點(diǎn)上被觸發(fā),然后逆向回流,知道傳播到最外層的文檔節(jié)點(diǎn)。

對(duì)于多層嵌套的節(jié)點(diǎn),鼠標(biāo)和指針事件經(jīng)常會(huì)被定位到最里層的元素上。假設(shè),你在一個(gè)div元素上設(shè)置了click的監(jiān)聽(tīng)函數(shù),而用戶點(diǎn)擊在了這個(gè)div元素內(nèi)部的p元素上,那么p元素就是這個(gè)時(shí)間的目標(biāo)元素。事件冒泡讓我們可以在這個(gè)div或者更上層的元素上監(jiān)聽(tīng)click事件,并且時(shí)間傳播過(guò)程中觸發(fā)回調(diào)函數(shù)。

冒泡階段(Bubble Phase)

事件在目標(biāo)事件上觸發(fā)后,并不在這個(gè)元素上終止。它會(huì)隨著DOM樹(shù)一層層向上冒泡,直到到達(dá)最外層的根節(jié)點(diǎn)。也就是說(shuō),同一事件會(huì)一次在目標(biāo)節(jié)點(diǎn)的父節(jié)點(diǎn),父節(jié)點(diǎn)的父節(jié)點(diǎn)...直到最外層的節(jié)點(diǎn)上觸發(fā)。

絕大多數(shù)事件是會(huì)冒泡的,但并非所有的。具體可見(jiàn):規(guī)范說(shuō)明

由上我們可以想到,可以使用事件代理來(lái)實(shí)現(xiàn)對(duì)每一個(gè)li的監(jiān)聽(tīng)。代碼如下:

復(fù)制代碼 代碼如下:

window.onload=function(){
  var ulNode=document.getElementById("list");
  ulNode.addEventListener('click',function(e){
       if(e.target&&e.target.nodeName.toUpperCase()=="LI"){/*判斷目標(biāo)事件是否為li*/
         alert(e.target.innerHTML);
       }
     },false);
};

以上所述就是本文的全部?jī)?nèi)容了,希望能夠?qū)Υ蠹沂煜avascript事件的委托和代理能夠有所幫助。

請(qǐng)您花一點(diǎn)時(shí)間將文章分享給您的朋友或者留下評(píng)論。我們將會(huì)由衷感謝您的支持!

相關(guān)文章

最新評(píng)論