首先,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件。举个例子,比如说送快递,如果一个快递员送一个公司的快递,他可以选择在公司联系每个人来取这个快递,当然另一种方法就是把快递让前台的MM代收,然后公司的人只要自己来前台取就ok了,虽然结果是一样的,但是效率却变快了许多。这里面可以把员工来取快递的行为看作是事件冒泡(什么是事件冒泡上篇文章有提)。
事件委托是通过事件冒泡实现的,所以如果子级的元素阻止了事件冒泡,那么事件委托也将失效!
下面代码是一个普通的事件绑定
<ul id="ul"> <li>aaaaaaaa</li> <li>bbbbbbbb</li> <li>cccccccc</li> </ul> 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 = ""; } } }
这样子我们可以通过for循环来遍历每一个li节点从而实现事件的绑定。但是有一个问题,上面代码只有三个dom界面,如果有需求需要的dom节点特别多,那么这就存在了性能的问题了。
我们通过event.target来实现事件委托,这里用到了事件源:event。什么是事件源呢?记住不管在那个事件中,只要你操作的那个元素就是事件源。
显而易见,这种方法就避免了for循环,从而提高了代码的性能,这也是事件委托的第一个好处:提高性能!
下面的代码是如何操作后添加的dom元素
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); } }这段代码用到了window.onload来实现事件的绑定,不过不用这个方法,那么事件肯定是失效。因为你绑定事件时根本就不存在这个dom元素,那么事件必然事件。
而事件委托就不会有这种问题。
window.onload = function(){ var oUl = document.getElementById("ul"); var aLi = oUl.getElementsByTagName("li"); var oBtn = document.getElementById("btn"); var iNow = 4; oUl.onmouseover = function(e){ var e = e || window.event; var target = e.target || e.srcElement; //alert(target.innerHTML); if(target.nodeName.toLowerCase() == "li"){ target.style.background = "red"; } } oUl.onmouseout = function(e){ var e = e || window.event; var target = e.target || e.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); } } IE:window.event.srcElement标准下:event.target nodeName:找到元素的标签名其实事件委托的核心不过是通过event.target(当前事件元素).nodeName(dom元素的标签名)取到标签,然后用event.target.style.xxx(例子中给的是background)来操作domwindow.event.srcElement是为了兼容ie下面是兼容浏览器写出的一个target事件 var e = e || window.event; var target = e.target || e.srcElement;这个如实事件委托的最核心,最有用的地方(个人认为),就是能够给后插入的dom节点绑定事件。一般我们用ajax调用接口返回的是一个大的json串,然后通过这个返回json动态插入数据(dom),这时候我们使用事件委托就不会出来事件绑定失效了。
这就是一个事件委托。其实最开始的事件委托是封装的bind(),live()和delegate(),
问题是,如果ul中要绑定1000个里,那么查找遍历1000个li会导致脚本运行速度很慢,而保存1000个li元素和事件处理程序也会占用大量的内存,所以这种方式我们不推荐。
转载于:https://www.cnblogs.com/jcscript/p/5634439.html
相关资源:数据结构—成绩单生成器