写了段简单事件委托,发觉stopListening一直没有执行handle,原来绑定的事件要一样!!
对于为什么要用事件委托:
事件委托是一个解决内存和性能的技巧。首先我们得知道为什么添加到页面上的事件处理数量会影响页面整体的运行性能:
每个函数都是对象,都会占用内存;内存中对象越多,性能越差。
必须事先指定所有事件处理程序而导致的DOM访问次数,会延迟整个页面的交互就绪事件。
解决 事件处理程序过多 的问题的解决方案就是 事件委托。
原理就是:为了不一个个遍历子节点绑定事件处理程序,把事件处理程序只绑定在包含这些子元素的父元素上,点击子节点,由于事件冒泡,绑定在父元素上的事件处理程序被处理,所以用户看到的效果跟遍历节点绑定事件处理程序的效果一样,而事件目标还是被点击的字节点。
而且如果使用遍历字节点去绑定事件处理程序,如果删除子节点,那些绑定在子节点上的事件处理程序还是没有移除的,必须得手动移除,如:element.οnclick=null,而采用事件委托也没有这烦恼
使用事件委托,不仅能提高性能,而且加入绑定事件处理程序的父元素中指向事件源的子元素还是有之前的事件的。一般,因为遍历是在新添加元素之前完成的,所以当我们新添加的元素进去后,事件处理程序是不可能绑定进去的。
简单的XHTML页面#ul{
display:table-cell;
width:400px;
height:400px;
list-style:none;
font:bold 60px "宋体";
margin:0px;
text-align:center;
vertical-align:middle;
border:1px solid #eee;
/* 针对ie的hack
*/
*display:block;
*font-size:175px;
}
var EventUtil = {
listenEvent:function(eventTarget,eventType,eventHandler){
eventTarget.addEventListener ?
eventTarget.addEventListener(eventType,eventHandler,false):
eventTarget.attachEvent?
eventTarget.attachEvent("on"+eventType,eventHandler):
eventTarget['on'+eventType] = eventHandler;
},
stopListening:function(eventTarget,eventType,eventHandler){
console.log("stop");
eventTarget.removeEventListener ?
eventTarget.removeEventListener(eventType,eventHandler,false):
eventTarget.detachEvent ?
eventTarget.detachEvent("on" + eventType,eventHandler):
eventTarget['on'+eventType] = null;
},
preventDefault:function(eventTarget){
eventTarget.preventDefault ? eventTarget.preventDefault:eventTarget.returnValue = false;
},
stopPropagation:function(eventTarget){
eventTarget.stopPropagation ? eventTarget.stopPropagation():eventTarget.cancleBubble = true;
},
evt:function(e){
return e || window.event;
},
evtTarget:function(e){
return e.target || e.srcElement;
}
};
window.onload = function(){
var oUl = $("ul");
var handler = function(ev){
console.log(ev);
var ev = EventUtil.evt(ev);
var target = EventUtil.evtTarget(ev);
if(target.nodeName.toLowerCase()=="li"){
target.style.background = "red";
}
};
EventUtil.listenEvent(oUl,"mouseover",handler);
EventUtil.stopListening(oUl,"mouseout",handler);
};
function $(sIdName){
return document.getElementById(sIdName);
}
/* 没有封装的写法...可以运行
function begin(){
var oUl = $("ul");
oUl.onmouseover = function(ev){
var ev = ev || window.event;
//event.stopPropagation();
//event.preventDefault();
var target = ev.target || ev.srcElement;
if(target.nodeName.toLowerCase()=="li"){
target.style.background = "red";
}
}
oUl.onmouseout = function(ev){
var ev = ev||window.event;
var target = ev.target ||ev.srcElement;
if(target.nodeName.toLowerCase()=="li"){
target.style.background = "";
}
}
}
window.onload = function(){
begin();
}
*/
- lgm
- zj
- ljm
- glt
有篇文章写得很好: