JavaScript事件委托的技术原理
来源:互联网 发布:淘宝8.8 编辑:程序博客网 时间:2024/06/06 13:04
本文转自:http://www.webhek.com/event-delegate/ 和 http://www.tuicool.com/articles/jQZj6zB
(1)
如今的JavaScript技术界里最火热的一项技术应该是‘事件委托(event delegation)’了。使用事件委托技术能让你避免对特定的每个节点添加事件监听器;相反,事件监听器是被添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件。基本概念非常简单,但仍有很多人不理解事件委托的工作原理。这里我将要解释事件委托是如何工作的,并提供几个纯JavaScript的基本事件委托的例子。
假定我们有一个UL
元素,它有几个子元素:
<span style="font-family:SimSun;"><span style="font-size:12px;"><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></span></span>
我们还假设,当每个子元素被点击时,将会有各自不同的事件发生。你可以给每个独立的li
元素添加事件监听器,但有时这些li
元素可能会被删除,可能会有新增,监听它们的新增或删除事件将会是一场噩梦,尤其是当你的监听事件的代码放在应用的另一个地方时。但是,如果你将监听器安放到它们的父元素上呢?你如何能知道是那个子元素被点击了?
简单:当子元素的事件冒泡到父ul
元素时,你可以检查事件对象的target属性,捕获真正被点击的节点元素的引用。下面是一段很简单的JavaScript代码,演示了事件委托的过程:
<span style="font-family:SimSun;"><span style="font-size:12px;">// 找到父元素,添加监听器...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!");}});</span></span>
第一步是给父元素添加事件监听器。当有事件触发监听器时,检查事件的来源,排除非
li
子元素事件。如果是一个li
元素,我们就找到了目标!如果不是一个li
元素,事件将被忽略。这个例子非常简单,UL
和li
是标准的父子搭配。让我们试验一些差异比较大的元素搭配。假设我们有一个父元素div
,里面有很多子元素,但我们关心的是里面的一个带有”classA” CSS类的A标记:<span style="font-family:SimSun;"><span style="font-size:12px;">// 获得父元素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....}}}}});</span></span>
上面这个例子中不仅比较了标签名,而且比较了CSS类名。虽然稍微复杂了一点,但还是很具代表性的。比如,如果某个A标记里有一个span
标记,则这个span
将会成为target元素。这个时候,我们需要上溯DOM树结构,找到里面是否有一个 A.classA 的元素。
因为大部分程序员都会使用jQuery等工具库来处理DOM元素和事件,我建议大家都使用里面的事件委托方法,因为这里工具库里都提供了高级的委托方法和元素甄别方法。
希望这篇文章能帮助你理解JavaScript事件委托的幕后原理,希望你也感受到了事件委托的强大用处!
(2)
1,什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件。
也就是:利用冒泡的原理,把事件加到父级上,触发执行效果。
好处:1,提高性能。
我们可以看一个例子:需要触发每个li来改变他们的背景颜色。
<span style="font-family:SimSun;"><ul id="ul"> <li>aaaaaaaa</li> <li>bbbbbbbb</li> <li>cccccccc</li></ul></span>
<span style="font-family:SimSun;">window.onload = function(){ var oUl = document.getElementById("ul"); var aLi = oUl.getElementsByTagName("li"); for(var i=0; i<aLi.length; i++){ aLi[i].onmouseover = function(){ this.style.background = "red"; } aLi[i].onmouseout = function(){ this.style.background = ""; } }}</span>
这样我们就可以做到li上面添加鼠标事件。
但是如果说我们可能有很多个li用for循环的话就比较影响性能。
下面我们可以用事件委托的方式来实现这样的效果。html不变
<span style="font-family:SimSun;">window.onload = function(){ var oUl = document.getElementById("ul"); var aLi = oUl.getElementsByTagName("li");</span>这里要用到事件源:event 对象,事件源,不管在哪个事件中,只要你操作的那个元素就是事件源。ie:window.event.srcElement标准下:event.targetnodeName:找到元素的标签名<span style="font-family:SimSun;"> oUl.onmouseover = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; //alert(target.innerHTML); if(target.nodeName.toLowerCase() == "li"){ target.style.background = "red"; } } oUl.onmouseout = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; //alert(target.innerHTML); if(target.nodeName.toLowerCase() == "li"){ target.style.background = ""; } }}</span>
好处2,新添加的元素还会有之前的事件。
我们还拿这个例子看,但是我们要做动态的添加li。点击button动态添加li
如:
<span style="font-family:SimSun;"><pre name="code" class="html"><pre name="code" class="html"><input type="button" id="btn" /><ul id="ul"> <li>aaaaaaaa</li> <li>bbbbbbbb</li> <li>cccccccc</li></ul></span>
不用事件委托我们会这样做:
<span style="font-family:SimSun;"><pre name="code" class="javascript">window.onload = function(){ var oUl = document.getElementById("ul"); var aLi = oUl.getElementsByTagName("li"); var oBtn = document.getElementById("btn"); var iNow = 4; for(var i=0; i<aLi.length; i++){ aLi[i].onmouseover = function(){ this.style.background = "red"; } aLi[i].onmouseout = function(){ this.style.background = ""; } } oBtn.onclick = function(){ iNow ++; var oLi = document.createElement("li"); oLi.innerHTML = 1111 *iNow; oUl.appendChild(oLi); }}</span>
这样做我们可以看到点击按钮新加的li上面没有鼠标移入事件来改变他们的背景颜色。
因为点击添加的时候for循环已经执行完毕。
那么我们用事件委托的方式来做。就是html不变
<span style="font-family:SimSun;">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; //alert(target.innerHTML); if(target.nodeName.toLowerCase() == "li"){ target.style.background = "red"; } } oUl.onmouseout = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; //alert(target.innerHTML); if(target.nodeName.toLowerCase() == "li"){ target.style.background = ""; } } oBtn.onclick = function(){ iNow ++; var oLi = document.createElement("li"); oLi.innerHTML = 1111 *iNow; oUl.appendChild(oLi); }}</span>
如同在我们用微博中,新发微博照样有之前的鼠标事件。
- javascript事件委托技术的原理
- JavaScript事件委托的技术原理
- JavaScript事件委托的技术原理
- JavaScript事件委托的技术原理
- JavaScript事件委托的技术原理
- JavaScript事件委托的技术原理
- JavaScript事件委托的技术原理
- JavaScript事件委托的技术原理
- JavaScript事件委托的技术原理
- JavaScript事件委托的技术原理
- JavaScript的事件委托技术
- 关于javascript的事件委托delegate的原理分析
- 关于编写性能高效的javascript事件的技术 ---事件委托
- JavaScript 事件委托 以及jQuery对事件委托的支持
- JavaScript 事件委托 以及jQuery对事件委托的支持
- 事件委托技术原理和使用(js,jquery)
- 事件委托技术原理和使用(js,jquery)
- vbscript以及javascript的事件委托方案
- 学习小组小记
- wifidog源码分析 - 认证服务器心跳检测线程
- selenium---sl4j日志输出
- 如何在安卓中把方形图变成圆形图
- 第十一周补充项目4-日期和时间类
- JavaScript事件委托的技术原理
- nyoj559 报数游戏
- kernel启动流程
- iframe跨域互相访问
- Asmack长链接框架使用
- Fast R-CNN笔记
- Java 设计模式-策略模式(Strategy)Android讲解
- Linux Shell编程(第一天)____入门
- 关于对ctype.h库中函数实现的理解