今天在公司,有个需求是,经过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。是的话触发对应的事件,从而 达到事件的委托。