1. 程式人生 > >javascript事件委託理解,jQuery on 方法一步到位實現事件委託

javascript事件委託理解,jQuery on 方法一步到位實現事件委託

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

本篇文章借鑑自:部落格園文章,只為自己鞏固下事件委託方面的知識

概述:

什麼叫事件委託?他還有一個名字叫做事件代理,(時間代理 === 事件委託,現在才知道這兩個是一個意思)

高程3上講:事件委託即是利用事件冒泡,只指定一個事件處理程式,就可以管理某一型別的所有事件。

借鑑其他大牛的一個例子,也為自己更好的理解一下:收快遞例子
有三個同事預計會在週一收到快遞。為簽收快遞,有兩種辦法:一是三個人在公司門口等快遞;二是委託給前臺MM代為簽收。現實當中,我們大都採用委託的方案(公司也不會容忍那麼多員工站在門口就為了等快遞)。前臺MM收到快遞後,她會判斷收件人是誰,然後按照收件人的要求籤收,甚至代為付款。這種方案還有一個優勢,那就是即使公司裡來了新員工(不管多少),前臺MM也會在收到寄給新員工的快遞後核實並代為簽收。

兩層意思: 1.現在委託前臺的同事是可以簽收的,即程式中的現有的dom節點是有事件的;
2.新員工也是可以被前臺mm代為簽收的,即程式中新新增的dom節點也是有事件的;
為什麼要用事件委託???事件委託有什麼好處???
一般來說,dom是需要有事件處理程式的,我們會直接給他事件處理程式就好了,那麼如果是很多dom元素需要新增事件處理呢??? 比如 100個li,每個li 都有相同的click點選事件,可能我們會有for迴圈的方法,來遍歷所有li,然後為每個li新增繫結事件。 這麼做毫無疑問的是對效能有很大的影響;
在js中,新增到頁面上的事件處理程式的多少將直接關係到頁面執行的整體效能,因為需要不斷的與dom節點進行互動,訪問dom次數越多,引起瀏覽器重繪與重排的次數也就越多,就會延長整個頁面的互動就緒時間。
這就是效能優化,減少dom操作的原因;
如果採用事件委託,就會將所有的操作放到js程式裡面,與dom的操作就只互動一次,這樣減少了dom互動次數,效能就會提升; 事件委託原理: 事件委託就是利用事件冒泡原理實現的! 事件冒泡:就是事件從最深節點開始,然後逐步向上傳播事件; 例:頁面上有一個節點樹,div > ul  > li  >  a 比如給最裡面的a 加一個click 事件,那麼事件就會一層一層的往外執行,執行順序 a > li > ul > div,  有這樣一個機制,當我們給最外層的div 新增點選事件,那麼裡面的ul , li  , a  做點選事件的時候,都會冒泡到最外層的div上,所以都會觸發,這就是事件委託,委託他們父集代為執行事件;
業務需求:實現功能,點選td ,單元格變色; html結構 [html]  view plain  copy
  1. <!-- 事件繫結 -->  
  2.     <table id="myTable" border="1">  
  3.         <tr>  
  4.             <td>1</td>  
  5.             <td>2</td>  
  6.             <td>3</td>  
  7.         </tr>  
  8.     </table>  
[javascript]  view plain  copy
  1. window.onload = function(){  
  2.     var oTa = document.getElementById("myTable");  
  3.     var aTd = oTa.getElementsByTagName('td');  
  4.     for(var i=0;i<aTd.length;i++){  
  5.         aTd[i].onclick = function(){  
  6.             aTd[i].style.background = 'red';  
  7.         }  
  8.     }  
  9. }  
上面的辦法是最簡單的辦法,也是最笨的辦法,我們看看執行了多少次dom操作,首先找到table 然後遍歷td ,當點選td的時候,又要找一次目標的li的位置,才能執行最後的操作,每次點選都要找一次td
那我們用 事件委託的方式怎麼來寫呢,??
[javascript]  view plain  copy
  1. window.onload = function(){  
  2.     var oTa= document.getElementById("myTable");  
  3.     oTa.onclick = function(){         //點選 table、td均可以alert(123)  
  4.        alert(123);    
  5.     }}  
[javascript]  view plain  copy
  1. <pre></pre>  
  2. <pre></pre>  
這裡用父集做事件處理,當td被點選時,由於冒泡原理事件就會冒泡到table上,因此table上有點選事件,所以事件就會被觸發;
當然單當點選table本身的時候也是會觸發的; 如果我們只想讓td觸發而不想讓table觸發,怎麼辦呢???
Event物件提供了一個屬性叫做 target,可以返回事件的目標節點,我們稱之為事件源,也就是說,target就可以表示 當前事件操作的dom,但可能不是真正操作的dom, 存在相容性問題:標準瀏覽器:event.target,IE瀏覽器:event.srcElement, 此時只是獲取了當前節點的位置,但並不知道節點名稱,這裡我們用 nodeName來獲取具體是什麼標籤名,這個返回值是一個大寫的,判斷時需要轉換為小寫; [javascript]  view plain  copy
  1. window.onload = function(){  
  2.   var oTa = document.getElementById("myTable");  
  3.   oTa.onclick = function(e){  
  4.     var e = e || window.event;                    //處理相容性  
  5.     var target = e.target || e.srcElement;     
  6.     target.nodeName.toLowerCase() == 'td' ? alert('我點中了table') :(target.style.background = 'red');  //三元運算子進行判斷  
  7.   }  
  8. }  
這樣改一下,就只有td會觸發事件啦,且每次只執行一次dom操作,如果td很多的話,將大大減小dom的操作; 上面的例子是說td點選都是產生同樣的效果,要是每個td被點選的效果都不一樣,那麼事件委託還有用嗎,??? [javascript]  view plain  copy
  1. <!-- 事件繫結 -->  
  2.     <table id="myTable" border="1">  
  3.         <tr>  
  4.             <td id="add">增加</td>  
  5.             <td id="delete">刪除</td>  
  6.             <td id="modfiy">修改</td>  
  7.             <td id="select">查詢</td>  
  8.         </tr>  
  9.     </table>  
非事件委託寫法 [javascript]  view plain  copy
  1. window.onload = function(){  
  2.             var Add = document.getElementById("add");  
  3.             var Delete = document.getElementById("delete");  
  4.             var Move = document.getElementById("move");  
  5.             var Select = document.getElementById("select");  
  6.               
  7.             Add.onclick = function(){  
  8.                 alert('新增');  
  9.             };  
  10.             Remove.onclick = function(){  
  11.                 alert('刪除');  
  12.             };  
  13.             Move.onclick = function(){  
  14.                 alert('移動');  
  15.             };  
  16.             Select.onclick = function(){  
  17.                 alert('選擇');  
  18.             }  
  19.               
  20.         }  
4個按鈕,點選每一個做不同的動作,,,那麼至少需要4次dom操作; 如果用事件委託,能進行優化嗎? 事件委託寫法
[javascript]  view plain  copy
  1. window.onload = function(){  
  2.             var myTable = document.getElementById("myTable");  
  3.             myTable.onclick = function (ev) {     
  4.                 var ev = ev || window.event;  
  5.                 var target = ev.target || ev.srcElement;  
  6.                 if(target.nodeName.toLocaleLowerCase() == 'table'){  
  7.                     switch(target.id){  
  8.                         case 'add' :  
  9.                             alert('新增');  
  10.                             break;  
  11.                         case 'remove' :  
  12.                             alert('刪除');  
  13.                             break;  
  14.                         case 'move' :  
  15.                             alert('移動');  
  16.                             break;  
  17.                         case 'select' :  
  18.                             alert('選擇');  
  19.