亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

javascript 中的事件委托詳解

 更新時(shí)間:2016年10月25日 09:01:03   投稿:lqh  
這篇文章主要介紹了javascript 中的事件委托詳解的相關(guān)資料,需要的朋友可以參考下

這幾天看到一個(gè)面試題,大概就是,讓你給1000個(gè)li都添加一個(gè)click事件,應(yīng)該怎么添加?大多數(shù)人第一開(kāi)始的感覺(jué)可能就是,每個(gè)li上邊都添加一個(gè)唄,那要是這樣的話,估計(jì)面試的時(shí)候就會(huì)GG了,這里就是撤出了我們的事件冒泡和捕獲機(jī)制,以及事件委托機(jī)制,對(duì)于上邊這些,我們慢慢來(lái)看.

  首先說(shuō)一下事件冒泡和事件捕獲機(jī)制,事件冒泡是有微軟公司提出來(lái)的,事件捕獲是有網(wǎng)景公司提出來(lái)的,當(dāng)時(shí)兩家是爭(zhēng)論的不可開(kāi)交,后來(lái)w3c也沒(méi)辦法,就采取了折中的方式,事件產(chǎn)生后先捕獲后冒泡,

  通常,在js中監(jiān)聽(tīng)事件的方法共有三種,分別是:

    ele.addEventListener(type,listener,[useCapture]);//IE6~8不支持

    ele.attachEvent('on'+type,listener);//IE6~10支持,IE11不支持

    ele.onClick=function(){};//所有瀏覽器都支持

  w3c規(guī)范中定義了三個(gè)事件階段,依次是捕獲階段,目標(biāo)階段,冒泡階段,而w3c指定的dom2級(jí)規(guī)定中,使用的是addEventListener來(lái)監(jiān)聽(tīng)事件的.所以我們就以addEventListener來(lái)講解,首先事假冒泡就像你從往水中扔一塊石子,水中的氣泡從下邊往上冒一樣,意思為觸發(fā)事件后從子元素王父元素方向觸發(fā),而捕獲機(jī)制則正好相反,捕獲機(jī)制是從父元素往子元素方向進(jìn)行事件觸發(fā),而addEventListener函數(shù)中的第三位參數(shù)正是來(lái)決定是使用捕獲機(jī)制還是冒泡機(jī)制的,當(dāng)useCapture為true是為捕獲機(jī)制,當(dāng)useCapture為false時(shí)是冒泡機(jī)制,我們看一下例子:

復(fù)制代碼

<div class="parent">
  <div class="child">

  </div>
</div>
<script>
  var parent = document.getElementsByClassName('parent')[0];
  var child = document.getElementsByClassName('child')[0];

  parent.addEventListener('click',function(){
    console.log("這里是父元素");
  },false);
  child.addEventListener('click',function(){
    console.log("這里是子元素");
  },false);
</script>

  當(dāng)我們點(diǎn)擊子元素是顯示上圖,當(dāng)我們將false改為true后就會(huì)發(fā)現(xiàn)執(zhí)行順序會(huì)反過(guò)來(lái),這就是事件冒泡和捕獲的區(qū)別,他們兩個(gè)剛好相反,

  那么使用這種綁定機(jī)制我們的弊端在于要去給每一個(gè)對(duì)象綁定事件會(huì)是一個(gè)特別麻煩的事情,當(dāng)我們要?jiǎng)h除一個(gè)事件或者要改變一個(gè)事件的時(shí)候會(huì)特別的繁瑣,更重要的是,我們?cè)黾恿薐avaScript和dom節(jié)點(diǎn)之間的關(guān)聯(lián),而且一點(diǎn)出現(xiàn)循環(huán)引用,很有可能造成內(nèi)存泄露,這些都是它的弊端,

   那么解決這種弊端的一種方法就是事件代理(event delegation),這個(gè)方法可以讓你避免去給每一個(gè)節(jié)點(diǎn)一一的添加事件,它的做法是將這些監(jiān)聽(tīng)事件去綁定到這些節(jié)點(diǎn)的父元素上,在父元素上的這個(gè)監(jiān)聽(tīng)函數(shù)自動(dòng)去判斷是哪一個(gè)子元素觸發(fā)的事件,從而可以對(duì)觸發(fā)事件的子元素進(jìn)行操作,這里我們給出的例子是davidwalsh所給出的一個(gè)例子:

   現(xiàn)在我們有一個(gè)父元素ul和幾個(gè)li子元素,

<ul id="parent-list">
  <li id="post-1">Item 1</li>
  <li id="post-2">Item 2</li>
  <li id="post-3">Item 3</li>
  <li id="post-4">Item 4</li>
  <li id="post-5">Item 5</li>
  <li id="post-6">Item 6</li>
</ul>

  現(xiàn)在我們要實(shí)現(xiàn)的是,當(dāng)我們點(diǎn)擊每一個(gè)li節(jié)點(diǎn)的時(shí)候,都會(huì)輸出li節(jié)點(diǎn)中的內(nèi)容,按照上邊的寫(xiě)法,你可以選中這些li,讓后給他們加上這些方法,然后等到不需要了再將他們移除,如果有100個(gè)li,1000個(gè)li呢,這將會(huì)成為你的噩夢(mèng),較好的解決方法就是給父元素添加一個(gè)監(jiān)聽(tīng)事件,之后的問(wèn)題便是怎么去判斷出來(lái)時(shí)哪一個(gè)li被點(diǎn)擊了? 我們可以在監(jiān)聽(tīng)事件中去判斷當(dāng)前event的target來(lái)判斷是否是我們要找的節(jié)點(diǎn),這里我們有一個(gè)簡(jiǎn)單的例子:

// 找到父元素,綁定一個(gè)監(jiān)聽(tīng)事件
document.getElementById("parent-list").addEventListener("click", function(e) {
  // e.target是點(diǎn)擊的元素
  // 如果它是li元素
  if(e.target && e.target.nodeName == "LI") {
    //
    console.log("List item ", e.target.id.replace("post-", ""), " was clicked!");
  }
});

  當(dāng)ul中發(fā)生點(diǎn)擊事件后,因?yàn)閍ddEventListener默認(rèn)是冒泡事件,所以監(jiān)聽(tīng)事件會(huì)在底層事件冒泡過(guò)來(lái)時(shí)執(zhí)行,在觸發(fā)了事件后,去檢測(cè)是否是我們要尋找的目標(biāo)元素,如果不是,就會(huì)忽略過(guò)去,那我們不僅僅可以通過(guò)目標(biāo)元素的標(biāo)簽是不是我們需要的目標(biāo)元素,我們還可以根據(jù)目標(biāo)元素的屬性或者類(lèi)名來(lái)進(jìn)行檢測(cè),利用ele.maeches這個(gè)API來(lái)進(jìn)行處理,

document.getElementById("myDiv").addEventListener("click",function(e) {
  // e.target 就是當(dāng)前被點(diǎn)擊的元素
 if (e.target && e.target.matches("a.classA")) {
  console.log("Anchor element clicked!");
  }
});

  因此我們可以看得出來(lái),使用事件代理這種方式,能夠給我們帶來(lái)很多的便捷,可以避免很多坑,使用事件代理是一種很強(qiáng)大的方法.

          感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

最新評(píng)論