事件委托概念:利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
首先封装好EventUtil以便兼容IE
var EventUtil = {
addHandler: function(element,type,handler){
if(element.addEventListener){//DOM2级事件,支持DOM事件流
element.addEventListener(type,handler,false);//冒泡阶段执行
}else if(element.attachEvent){//IE:attachEvent("onclick",func)
element.attachEvent("on"+type,handler);
}else{//DOM0级事件
element["on"+type] = handler;
}
},
getEvent: function(event){//IE:window.event
return event ? event : window.event;
},
getTarget: function(event){//事件的目标
return event.target || event.srcElement;
},
preventDefault: function(event){//阻止默认行为
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue = false;//IE阻止默认行为
}
},
stopPropagation: function(event){//阻止冒泡
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble = true;//IE取消冒泡
}
}
}
需求:有一个ul中包含三个li标签,分别对三个li标签执行点击事件,不同的结果
<ul id="myLinks">
<li id="goSomewhere">1</li>
<li id="doSth">2</li>
<li id="sayHi">3</li>
</ul>
方案一:
var myLinks = document.getElementById("myLinks");
var item1 = document.getElementById("goSomewhere");
var item2 = document.getElementById("doSth");
var item3 = document.getElementById("sayHi");
EventUtil.addHandler(item1,"click",function(event){
location.href = "http://baidu.com";
})
EventUtil.addHandler(item2,"click",function(event){
document.title = "I am title";//改变文档标题
})
EventUtil.addHandler(item3,"click",function(event){
alert("hi");
})
方案一分析:如果程序比较复杂,点击事件比较多需要添加多个事件处理程序,就会有很多代码用于点击事件,可以使用事件委托,在DOM树中尽量高的层次添加一个事件处理程序,具体如下:
方案二:
var myLinks = document.getElementById("myLinks");
EventUtil.addHandler(myLinks,"click",function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(target.id){
case "goSomewhere":
location.href = "http://baidu.com";
break;
case "doSth":
document.title = "I am title";
break;
case "sayHi":
alert("hi");
break;
}
})
方案二分析:上面的代码我们只给ul添加了一个onclick事件处理程序,由于所有列表元素都是这个元素的子节点,并且他们的事件都会冒泡,所以单击事件最终会被这个函数处理,与前面相比,只取了一个DOM元素,只添加了一个事件处理程序。
--JavaScript高级程序设计