最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入分析Javascript事件代理

 更新時間:2016年01月30日 09:32:40   投稿:hebedich  
JavaScript事件是所有網(wǎng)頁互動性的根基。在傳統(tǒng)的事件處理中,事件處理器將有可能導(dǎo)致內(nèi)存泄露或者是性能下降,JavaScript事件代理則是一種簡單的技巧,通過它你可以把事件處理器添加到一個父級元素上,這樣就避免了把事件處理器添加到多個子級元素上。

很久很久以來,總感覺事件發(fā)生與事件代理到之間沒什么鳥區(qū)別。

最近,又看了一下,感覺區(qū)別其實真不大!看怎么理解吧。

要搞清楚什么是事件代理,就需要先搞清楚什么是代理。

從商業(yè)角度來講,代理就是:我有貨,你沒貨,但丫我沒時間、沒精力全部賣掉,而你一天閑的蛋疼,只剩下時間了。于是,我委托你幫我買,然后哥給你提成。這個過程中,你實際上相當(dāng)于也有了貨。

OK,怎么從字面來理解事件代理一詞的含義?后文有講。

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

如果按照之前的我,我會怎么給每一個li標(biāo)簽,添加onlick呢?廢話,要是我,肯定簡單粗暴。
循環(huán)每一個li,然后全部綁定onlick。

于是我的代碼應(yīng)該是這樣子:

<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>

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

二 突然有一天,我發(fā)現(xiàn)通過js添加進(jìn)來的新的li,沒有綁定onlcik

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

然后,點(diǎn)擊maomaoliang,它并沒有綁定我的onlick,這是為什么?
哦,原來,我原有的li跟我后面生成的li根本不是同時發(fā)生的,在創(chuàng)建新的li元素之前,已經(jīng)給存在的li加事件了。好吧,好煩啊。

三 那怎么破?

然后,又好(無)奇(奈)的看了一些文章,原來有個叫事件代理的東西可以用。我就試試看吧!于是改寫了部分代碼,像這樣:

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

結(jié)果,點(diǎn)擊新的li,居然也觸發(fā)了fn函數(shù)。好吧,身為一個好奇心驅(qū)動的肉身,我怎么能不求甚解呢?還是要踏實點(diǎn),搞清楚這其中的奧秘才行。

于是,看了事件代理的資料。

首先,要知道什么是事件冒泡:當(dāng)一個元素上的事件被觸發(fā)的時候,比如說鼠標(biāo)點(diǎn)擊了一個按鈕,同樣的事件將會在那個元素的所有祖先元素中被觸發(fā)。這一過程被稱為事件冒泡。

然后,再回到之前的問題“怎么從字面來理解事件代理一詞的含義”,誰代理了事件?或者事件代理了誰?
以本文的例子來講,看看改動后的代碼,我把onlick事件綁定到了ul標(biāo)簽上面,而不是li標(biāo)簽。于是,當(dāng)我點(diǎn)擊任何一個li標(biāo)簽(不管是動態(tài)生成的還是之前就有的)是,這個事件就像泡泡一樣,冒啊冒。正常的情況下,ul也會綁定onclick,body也會綁定到onclick,也就說它會冒泡到最根層的元素。但我這里給ul綁定了onlick,那么這時,ul會把泡泡截住,事件也就停止上升,無法抵達(dá)body標(biāo)簽。

接著, var target = ev.target || ev.srcElement;這一句話,相當(dāng)于告訴了我,我究竟點(diǎn)的是誰,誰才是target。如果,這個target剛剛好就是li標(biāo)簽if (target.nodeName.toLowerCase() == 'li'),那么執(zhí)行fn函數(shù)。

最后,我驕傲的回答了那個問題:table代理了onlick事件!

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

父元素綁定事件
父元素知道事件的實際發(fā)生目標(biāo)是誰
我們要對目標(biāo)進(jìn)行判斷,如果是我們需要的元素,則發(fā)生回調(diào)函數(shù)(所以要學(xué)好選擇器的使用)

五 最后總結(jié),事件代理兩大好處

性能不小心得到了優(yōu)化
動態(tài)添加的元素也能綁定事件了

六 需要注意的一點(diǎn)是

上述針對的是原生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標(biāo)簽,也能綁click,是不是很方便、很簡單,是不是感覺學(xué)js沒什么卵用。

哈哈,這樣想很正常,我以前也這么想,但是,做了一些東西之后,發(fā)現(xiàn)jquery還真的不夠用了!但是基本夠用!

雖然,大神們都說要學(xué)js,但我還是覺得可以先學(xué)jquery,之后再學(xué)js,效果也可以的。

相關(guān)文章

  • 優(yōu)化RequireJS項目的相關(guān)技巧總結(jié)

    優(yōu)化RequireJS項目的相關(guān)技巧總結(jié)

    這篇文章主要介紹了優(yōu)化RequireJS項目的相關(guān)技巧總結(jié),RequireJS是一個人氣JavaScript庫,需要的朋友可以參考下
    2015-07-07
  • parentElement,srcElement的使用小結(jié)

    parentElement,srcElement的使用小結(jié)

    本篇文章主要是對parentElement,srcElement的使用進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • javascript操作符

    javascript操作符"!~"詳解

    這篇文章主要詳細(xì)介紹了javascript操作符"!~",最基本也最容易忽略的東西,混了幾年連基本都沒了,被人問到得貽笑大方。
    2015-02-02
  • JavaScript學(xué)習(xí)筆記整理_用于模式匹配的String方法

    JavaScript學(xué)習(xí)筆記整理_用于模式匹配的String方法

    下面小編就為大家?guī)硪黄狫avaScript學(xué)習(xí)筆記整理_用于模式匹配的String方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • 最新評論

    双牌县| 雅江县| 嘉黎县| 长子县| 如东县| 津南区| 西峡县| 温州市| 昌吉市| 小金县| 奎屯市| 榆林市| 清流县| 县级市| 涞水县| 桃源县| 南部县| 壤塘县| 江永县| 内江市| 修文县| 咸阳市| 霍林郭勒市| 阿荣旗| 荃湾区| 玉龙| 安泽县| 正镶白旗| 平陆县| 开远市| 观塘区| 锦屏县| 鹤峰县| 安庆市| 比如县| 和林格尔县| 鹿邑县| 临高县| 秀山| 浏阳市| 沽源县|