Javascript事件代理の真理

參考資料:js-事件代理html

好久好久以來,總感受事件發生與事件代理到之間沒什麼鳥區別。node

最近,又看了一下,感受區別其實真不大!看怎麼理解吧。jquery

要搞清楚什麼是事件代理,就須要先搞清楚什麼是代理。app

從商業角度來說,代理就是:我有貨,你沒貨,但丫我沒時間、沒精力所有賣掉,而你一天閒的蛋疼,只剩下時間了。因而,我委託你幫我買,而後哥給你提成。這個過程當中,你實際上至關於也有了貨。函數

OK,怎麼從字面來理解事件代理一詞的含義?後文有講。性能


一 先看一個真實的,新手綁定onclik事件的例子

若是按照以前的我,我會怎麼給每個li標籤,添加onlick呢?廢話,要是我,確定簡單粗暴。
循環每個li,而後所有綁定onlick。優化

因而個人代碼應該是這樣子:代理

<ul id="thl">
   <li>001</li>
   <li>002</li>
   <li>003</li>
</ul>

<script>
    var thl= document.getElementById('thl');
    var aLi = thl.getElementsByTagName('li');
    for (var i = 0; i < aLi.length; i++) {
      aLi[i].onclick = fn;
    }
    
    function fn (){
      console.log("maomaoliang");
    }
</script>

好像看起來沒問題了。雖然,有些文章說這樣很消耗性能,可是,我丫電腦好,老子管你性能,不能太認真。code

二 忽然有一天,我發現經過js添加進來的新的li,沒有綁定onlcik

var node=document.createElement("li");
var textnode=document.createTextNode("maomaoliang");
node.appendChild(textnode);
document.getElementById("ul1").appendChild(node);

而後,點擊maomaoliang,它並無綁定個人onlick,這是爲何?
哦,原來,我原有的li跟我後面生成的li根本不是同時發生的,在建立新的li元素以前,已經給存在的li加事件了。好吧,好煩啊。htm

三 那怎麼破?

而後,又好(無)奇(奈)的看了一些文章,原來有個叫事件代理的東西能夠用。我就試試看吧!因而改寫了部分代碼,像這樣:

var thl= document.getElementById('thl');
thl.onclick = function(ev) {
    ev = ev || event;
    //兼容處理
    var target = ev.target || ev.srcElement;
  //找到li元素
    if (target.nodeName.toLowerCase() == 'li') {
          fn();
     }
};

function fn (){
  console.log("maomaoliang");
}

結果,點擊新的li,竟然也觸發了fn函數。好吧,身爲一個好奇心驅動的肉身,我怎麼能不求甚解呢?仍是要踏實點,搞清楚這其中的奧祕才行。

因而,看了事件代理的資料。

首先,要知道什麼是事件冒泡:當一個元素上的事件被觸發的時候,好比說鼠標點擊了一個按鈕,一樣的事件將會在那個元素的全部祖先元素中被觸發。這一過程被稱爲事件冒泡。

而後,再回到以前的問題「怎麼從字面來理解事件代理一詞的含義」,誰代理了事件?或者事件代理了誰?
以本文的例子來說,看看改動後的代碼,我把onlick事件綁定到了ul標籤上面,而不是li標籤。因而,當我點擊任何一個li標籤(不論是動態生成的仍是以前就有的)是,這個事件就像泡泡同樣,冒啊冒。因爲我這裏給ul綁定了onlick,那麼這時,ul會捕獲冒泡上來的onclick事件。

接着, var target = ev.target || ev.srcElement;這一句話,至關於告訴了我,我究竟點的是誰,誰纔是target。若是,這個target剛恰好就是li標籤if (target.nodeName.toLowerCase() == 'li'),那麼執行fn函數。

最後,我驕傲的回答了那個問題:ul標籤代理了onlick事件!

四 回憶一下事件代理的步驟

  1. 父元素綁定事件

  2. 父元素知道事件的實際發生目標是誰

  3. 咱們要對目標進行判斷,若是是咱們須要的元素,則發生回調函數(因此要學好選擇器的使用)

五 最後總結,事件代理兩大好處

  1. 性能不當心獲得了優化

  2. 動態添加的元素也能綁定事件了

六 須要注意的一點是

上述針對的是原生js事件綁定來說的,若是你用到了jquery。並把代碼改爲了以下的樣子:

/*var thl= document.getElementById('ul1');
thl.onclick = function(ev) {
    ev = ev || event;
    //兼容處理
    var target = ev.target || ev.srcElement;
  //找到li元素
    if (target.nodeName.toLowerCase() == 'li') {
          //li添加的事件
          fn();
     }
};*/

var node=document.createElement("li");
var textnode=document.createTextNode("maomaoliang");
node.appendChild(textnode);
document.getElementById("ul1").appendChild(node);

function fn (){
  console.log("maomaoliang");
}

$("#ul1").click(function(){
    fn();
});

這樣一來,新添加的li標籤,也能綁click,是否是很方便、很簡單,是否是感受學js沒什麼卵用。
哈哈,這樣想很正常,我之前也這麼想,可是,作了一些東西以後,發現jquery還真的不夠用了!可是基本夠用!
雖然,大神們都說要學js,但我仍是以爲能夠先學jquery,以後再學js,效果也能夠的。

大神嘛,哪懂叼絲的痛楚。-。-

相關文章
相關標籤/搜索