JavaScript事件委托的技术原理

现在的JavaScript技术界里最火热的一项技术应该是‘事件委托(event delegation)’了。使用事件委托技术能让你避免对特定的每一个节点添加事件监听器;相反,事件监听器是被添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,找到是哪一个子元素的事件。基本概念很是简单,但仍有不少人不理解事件委托的工做原理。这里我将要解释事件委托是如何工做的,并提供几个纯JavaScript的基本事件委托的例子。html

假定咱们有一个UL元素,它有几个子元素:node

<ul id="parent-list"> <li id="post-1">Item 1</li> <li id="post-2">Item 2</li> <li id="post-3">Item 3</li> <li id="post-4">Item 4</li> <li id="post-5">Item 5</li> <li id="post-6">Item 6</li> </ul>

现在的JavaScript技术界里最火热的一项技术应该是‘事件委托(event delegation)’了。使用事件委托技术能让你避免对特定的每一个节点添加事件监听器;相反,事件监听器是被添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,找到是哪一个子元素的事件。基本概念很是简单,但仍有不少人不理解事件委托的工做原理。这里我将要解释事件委托是如何工做的,并提供几个纯JavaScript的基本事件委托的例子。程序员

假定咱们有一个UL元素,它有几个子元素:工具

<ul id="parent-list"> <li id="post-1">Item 1</li> <li id="post-2">Item 2</li> <li id="post-3">Item 3</li> <li id="post-4">Item 4</li> <li id="post-5">Item 5</li> <li id="post-6">Item 6</li> </ul>

咱们还假设,当每一个子元素被点击时,将会有各自不一样的事件发生。你能够给每一个独立的li元素添加事件监听器,但有时这些li元素可能会被删除,可能会有新增,监听它们的新增或删除事件将会是一场噩梦,尤为是当你的监听事件的代码放在应用的另外一个地方时。可是,若是你将监听器安放到它们的父元素上呢?你如何能知道是那个子元素被点击了?post

简单:当子元素的事件冒泡到父ul元素时,你能够检查事件对象的target属性,捕获真正被点击的节点元素的引用。下面是一段很简单的JavaScript代码,演示了事件委托的过程:spa

// 找到父元素,添加监听器...
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标记:code

// 得到父元素DIV, 添加监听器...
document.getElementById("myDiv").addEventListener("click",function(e) { // e.target是被点击的元素 if(e.target && e.target.nodeName == "A") { // 得到CSS类名 var classes = e.target.className.split(" "); // 搜索匹配! if(classes) { // For every CSS class the element has... for(var x = 0; x < classes.length; x++) { // If it has the CSS class we want... if(classes[x] == "classA") { // Bingo! console.log("Anchor element clicked!"); // Now do something here.... } } } } });

上面这个例子中不只比较了标签名,并且比较了CSS类名。虽然稍微复杂了一点,但仍是很具表明性的。好比,若是某个A标记里有一个span标记,则这个span将会成为target元素。这个时候,咱们须要上溯DOM树结构,找到里面是否有一个 A.classA 的元素。htm

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

但愿这篇文章能帮助你理解JavaScript事件委托的幕后原理,但愿你也感觉到了事件委托的强大用处!token

相关文章
相关标签/搜索