项目开发中经常需要为动态创建的节点绑定事件,
比如需要创建一个动态列表:在li的数量非常少的时候,为每一个li绑定事件不会存在太多性能方面的问题,但是当列表非常的长,长到上百上千甚至上万的时候(假设),为每个li绑定事件就会对页面性能产生很大的影响。当有大量元素需要绑定相同事件的时候可采用事件委托,将在目标元素上要处理的事件委托给父元素或者祖先元素
优点
事件委托对于web应用程序的性能有如下几个优点: 1.需要管理的函数变少了 2.占用的内存少了 3.javascript代码和Dom结构之间的关联更少了首先动态创建节点:
点击按钮 创建一个li节点并将文本框中输入的值做为此节点的内容,新创建的LI节点插入到最前面
HTML代码:
1 2 3 4
- 5
其次为LI中的A元素绑定点击事件:点击A元素删除所在的LI节点
采用事件委托,有如下两种方法供大家参考:
方法一:传统绑定 [直接给元素绑定事件]
1 2 3 4
- 5
方法1: a、优点:
1、简单可靠,确保在不同的浏览器中保持一致;
2、处理事件时,this关键字引用的是当前的元素;
b、缺点:
1、只支持冒泡阶段的运行;
2、一个元素一次只能绑定一个事件处理函数,同类事件处理函数会相互覆盖;[如给同一元素绑定两次.onclick事件,则只有最后一个绑定成功]
方式二:事件监听
在IE6-8下可用attachEvent,在IE9,谷歌和火狐下则要用addEventListener
若为同一元素多次绑定,则会产生追加的效果,事件触发是的执行顺序,由下至上 attachEvent()有两个参数 第一个是事件名称 第二个是需执行的函数; addEventListener()有三个参数 第一个是事件名称,但与IE事件不同的是,事件不带"on",比如"onsubmit"在这里应为"submit" 第二个是需执行的函数 第三个参数为布尔值,表示该事件的响应顺序(useCapture),userCapture若为true,则浏览器采用Capture[捕获], 若为false则采用bubbing[冒泡]方式。对函数进行封装后兼容各大主流浏览器的监听事件如下:
1 /* 2 * oTarget:监听对象 3 * sEventType:监听事件类型,如click,mouseover 4 * fnHandler:监听函数 5 */ 6 function addEventHandler(oTarget, sEventType, fnHandler) { 7 if (oTarget.addEventListener) { //监听IE9,谷歌和火狐 8 oTarget.addEventListener(sEventType, fnHandler, false); 9 } else if (oTarget.attachEvent) { //IE 10 oTarget.attachEvent("on" + sEventType, fnHandler); 11 } else { 12 oTarget["on" + sEventType] = fnHandler; 13 } 14 }
HTML代码:
1 2 3 4
- 5
既然讲到了采用事件监听给对象绑定方法,那也顺便说说解除相应的绑定
在IE6-8下可用detachEvent,在IE9,谷歌和火狐下则要用removeEventListener
对函数进行封装后兼容各大主流浏览器的解除事件监听方法如下:
1 /* 2 * 采用事件监听给对象绑定方法后,可以解除相应的绑定 3 * oTarget:监听对象 4 * sEventType:监听事件类型,如click,mouseover 5 * fnHandler:监听函数 6 */ 7 function removeEventHandler(oTarget, sEventType, fnHandler) { 8 if (oTarget.removeEventListener){ 9 //监听IE9,谷歌和火狐 10 oTarget.removeEventListener(sEventType, fnHandler, false); 11 } else if (oTarget.detachEvent){ 12 oTarget.detachEvent("on" + sEventType, fnHandler); 13 }else { 14 delete oTarget["on" + sEventType]; 15 } 16 }
HTML代码:
1 2 3
- 4
注:解除绑定事件的时候一定要用函数的句柄,把整个函数写上是无法解除绑定的
1 //正确写法 2 removeEventHandler(oul,'click',fnHandle); 3 4 //错误写法 5 removeEventHandler(oul,'click',function(e) 6 { 7 e = e || window.event; //IE window.event 8 var t = e.target || e.srcElement; //目标对象 9 var classname = t.className;10 if( classname == 'ac' )11 {12 oul.removeChild(t.parentNode);13 } 14 });
方法一解除绑定:oul.onclick = null;
总结:
方法一和方法二的区别:
当同一个对象使用.onclick的写法触发多个方法的时候,后一个方法会把前一个方法覆盖掉,也就是说,在对象的onclick事件发生时,只会执行最后绑定的方法。而用事件监听则不会有覆盖的现象,每个绑定的事件都会被执行,也便于解除事件绑定