当给一个ul动态的添加一个li以后,console.log点击没有事件弹出node
1 window.onload = function () { 2 var oUl=document.querySelector(".oUl"); 3 var aLi=document.querySelectorAll(".oUl li"); 4 5 for(var i=0;i<aLi.length;i++){ 6 aLi[i].onclick=function () { 7 console.log(this.innerHTML); 8 } 9 } 10 oUl.innerHTML+="<li>lll</li>" 11 } 12 13 14 <ul class="oUl"> 15 <li>aaaaa</li> 16 <li>aaaaa</li> 17 <li>aaaaa</li> 18 <li>aaaaa</li> 19 <li>aaaaa</li> 20 </ul>
点击最后一个动态添加的li没有反应,因此,在这里解决这个问题就须要用到事件委托。程序员
使用事件委托技术能让你避免对特定的每一个节点添加事件监听器;相反,事件监听器是被添加到他们的父元素上,事件监听器会分析从子元素冒泡上来的事件,找到哪一个子元素的事件。工具
当子元素的事件冒泡到父ul
元素时,你能够检查事件对象的target属性,捕获真正被点击的节点元素的引用。下面是一段很简单的JavaScript代码,演示了事件委托的过程:post
// 找到父元素,添加监听器... document.getElementById("parent-list").addEventListener("click",function(e) { // e.target是被点击的元素! // 若是被点击的是li元素 if(e.target && e.target.nodeName == "LI") { // 找到目标,输出ID! console.log("List item ",e.target.id.replace("post-")," was clicked!"); } });
第一步是给父元素添加事件监听器。当有事件触发监听器时,检查事件的来源,排除非li
子元素事件。若是是一个li
元素,咱们就找到了目标!若是不是一个li
元素,事件将被忽略。这个例子很是简单,UL
和li
是标准的父子搭配。让咱们试验一些差别比较大的元素搭配。假设咱们有一个父元素div
,里面有不少子元素,但咱们关心的是里面的一个带有”classA” CSS类的A标记:this
1 // 得到父元素DIV, 添加监听器... 2 document.getElementById("myDiv").addEventListener("click",function(e) { 3 // e.target是被点击的元素 4 if(e.target && e.target.nodeName == "A") { 5 // 得到CSS类名 6 var classes = e.target.className.split(" "); 7 // 搜索匹配! 8 if(classes) { 9 // For every CSS class the element has... 10 for(var x = 0; x < classes.length; x++) { 11 // If it has the CSS class we want... 12 if(classes[x] == "classA") { 13 // Bingo! 14 console.log("Anchor element clicked!"); 15 16 // Now do something here.... 17 18 } 19 } 20 } 21 22 } 23 });
上面这个例子中不只比较了标签名,并且比较了CSS类名。虽然稍微复杂了一点,但仍是很具表明性的。好比,若是某个A标记里有一个span
标记,则这个span
将会成为target元素。这个时候,咱们须要上溯DOM树结构,找到里面是否有一个 A.classA 的元素。spa
由于大部分程序员都会使用jQuery等工具库来处理DOM元素和事件,我建议你们都使用里面的事件委托方法,由于这里工具库里都提供了高级的委托方法和元素甄别方法。code