代码改变世界

关于js中事件委托的技术原理

2016-10-12 17:04  sunhengkai941022  阅读(516)  评论(0)    收藏  举报

当给一个ul动态的添加一个li之后,console.log点击没有事件弹出

 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代码,演示了事件委托的过程:

// 找到父元素,添加监听器...
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元素,事件将被忽略。这个例子非常简单,ULli是标准的父子搭配。让我们试验一些差异比较大的元素搭配。假设我们有一个父元素div,里面有很多子元素,但我们关心的是里面的一个带有”classA” CSS类的A标记:

 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 的元素。

因为大部分程序员都会使用jQuery等工具库来处理DOM元素和事件,我建议大家都使用里面的事件委托方法,因为这里工具库里都提供了高级的委托方法和元素甄别方法。