今天在公司,有個需求是,經過ajax動態查詢數據,回來,再添加到一個ul的li元素中,例如(點擊生成 li 模擬,加載數據生成相應的數據, 事件: 點擊):javascript
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Document</title> <script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script> </head> <body> <button>create</button> <ul id="parent"> <li class="son-1">Item 1</li> <li class="son-2">Item 2</li> </ul> <script> $(function () { $('button').on('click', function (e) { $('#parent').append('<li>add</li>') }); }); </script> </body> </html>
平時本身的添加事件:html
$('#parent li').on('click', function (e) { alert('這是第' + $(this).index() + 'li'); });
這樣子能夠爲,dom元素中已經通過渲染的li元素綁定事件,若是點擊 craete按鈕新生成的li元素,因爲,事件綁定的js已經執行完畢,因此沒法對新生成的li進行事件的綁定。一開始,在沒有用jq的事件委託,本身簡單的粗暴的對新生的元素,再一次動態綁定:java
//在生成新生元素後, 再次執行這段 函數 ,綁定須要的事件。 $('#parent li').on('click', function (e) { alert('這是第' + $(this).index() + 'li'); });
明顯是很挫的作法,不只不易維護,並且性能也大打折扣,由於這樣雖然會爲新的元素綁定到事件,可是已經存在的元素也會再次綁。node
jq提供的事件委託,能夠頗有效的解決這種問題。delegate 和 on 都提供了相應的方法jquery
$('#parent').delegate('li', 'click', function(event) { console.log($(this)) });
$('#parent').on('click', 'li', function (e) { console.log($(this)) });
這兩個函數都可提供相應的效果,我的更傾向於使用 on :ajax
下面是從jq的api copy過來的使用文檔:api
在選擇元素上綁定一個或多個事件的事件處理函數。app
on()方法綁定事件處理程序到當前選定的jQuery對象中的元素。在jQuery 1.7中,.on()方法 提供綁定事件處理程序所需的全部功能。幫助從舊的jQuery事件方法轉換,see .bind(), .delegate(), 和 .live(). 要刪除的.on()綁定的事件,請參閱.off()。要附加一個事件,只運行一次,而後刪除本身, 請參閱.one()dom
events:一個或多個用空格分隔的事件類型和可選的命名空間,如"click"或"keydown.myPlugin" 。函數
selector:一個選擇器字符串用於過濾器的觸發事件的選擇器元素的後代。若是選擇的< null或省略,當它到達選定的元素,事件老是觸發。
data:當一個事件被觸發時要傳遞event.data給事件處理函數。
fn:該事件被觸發時執行的函數。 false 值也能夠作一個函數的簡寫,返回false。
events-map:個用字符串表示的,一個或多個空格分隔的事件類型和可選的命名空間,值表示事件綁定的處理函數。
selector:一個選擇器字符串過濾選定的元素,該選擇器的後裔元素將調用處理程序。若是選擇是空或被忽略,當它到達選定的元素,事件老是觸發。
data:當一個事件被觸發時要傳遞event.data給事件處理函數。
javascript也有原生的事件委託
DEMO:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <input type="button" id="btn" /> <ul id="ul"> <li>aaaaaaaa</li> <li>bbbbbbbb</li> <li>cccccccc</li> </ul> <script> window.onload = function(){ var oUl = document.getElementById("ul"); var aLi = oUl.getElementsByTagName("li"); var oBtn = document.getElementById("btn"); var iNow = 4; oUl.onmouseover = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == "li"){ alert('觸發了') } } oUl.onmouseout = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == "li"){ alert('觸發了') } } oBtn.onclick = function(){ iNow ++; var oLi = document.createElement("li"); oLi.innerHTML = iNow; oUl.appendChild(oLi); } } </script> </body> </html>
從原生的js中能夠看出:事件委託是經過,事件的冒泡。實現的。經過子元素的點擊事件,冒泡到父元素,父元素再經過event的內容判斷 爲該元素觸發相應的事件, 在demo中的,獲取對應的 tagName 判斷子元素 是否是 li。是的話觸發對應的事件,從而 達到事件的委託。