深入分析Javascript事件代理,深入分析javascript

來源:互聯網
上載者:User

深入分析Javascript事件代理,深入分析javascript

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

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

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

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

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

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

如果按照之前的我,我會怎麼給每一個li標籤,添加onlick呢?廢話,要是我,肯定簡單粗暴。
迴圈每一個li,然後全部綁定onlick。

於是My Code應該是這樣子:

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

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

二 突然有一天,我發現通過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加事件了。好吧,好煩啊。

三 那怎麼破?

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

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也會綁定onclick,body也會綁定到onclick,也就說它會冒泡到最根層的元素。但我這裡給ul綁定了onlick,那麼這時,ul會把泡泡截住,事件也就停止上升,無法抵達body標籤。

接著, var target = ev.target || ev.srcElement;這一句話,相當於告訴了我,我究竟點的是誰,誰才是target。如果,這個target剛剛好就是li標籤if (target.nodeName.toLowerCase() == 'li'),那麼執行fn函數。

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

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

父元素繫結事件
父元素知道事件的實際發生目標是誰
我們要對目標進行判斷,如果是我們需要的元素,則發生回呼函數(所以要學好選取器的使用)

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

效能不小心得到了最佳化
動態添加的元素也能綁定事件了

六 需要注意的一點是

上述針對的是原生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,效果也可以的。

您可能感興趣的文章:
  • javascript中的事件代理初探
  • JavaScript的事件代理和委託執行個體分析
  • JavaScript通過事件代理高亮顯示表格行的方法
  • 淺析javascript中的事件代理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.