接着上文:果然是实践多经验,遇到卡住的地方解决了心里甚是舒畅
第二部分,我实现点击菜单栏,切换主页的框架内容
由于我菜单栏里的菜单有3个以上的菜单,为了避免多次通过getElementById()来读取元素,因此我决定使用事件委托 来解决读取问题。
先说说我对事件委托的一个认识和理解:
事件委托,主要是通过事件的冒泡阶段的特性来解决性能的问题,事件有两个阶段捕获阶段和冒泡阶段。
在捕获过程中,事件会从最外层元素<html>向最内部元素,例如<button>一直处于被捕获状态,直到某层元素发生了事件,则进行冒泡阶段。冒泡阶段的顺序与捕获阶段相反,因此在内部元素触发的事件,同时会使外部的元素触发。
因此,就有了一个事件委托的解决方法,实现功能主要关键在于事件处理程序建立在需要处理多个子元素的父元素上。
第一步:上文我提到一个跨浏览器兼容问题,为了避免IE事件与DOM事件差异,需要创建一个EventUtil变量来储存兼容方法。
var EventUtil={
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);}
else if(element.attachEvent){
element.attachEvent("on"+type,handler);
}else{element["on"+type]=handler;}
}
,
removeHandler:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false);}
else if(element.detachEvent){
element.detachEvent("on"+type,handler);
}else{element["on"+type]=null;}
}
,
getEvent:function(event){return event?event:window.event;},
getTarget:function(event){return event.target||event.srcElement;}
}
同时,我们要知道event和event、event.target、event.currentTarget的关系:
<button id="btn" value="clickme" οnclick="alert(event)"></button>
警示框弹出的结果是:MouseEvent(鼠标事件) ,若换成 event.type,则是click事件;
event.target => button Element ; event.target.id => btn
(在这里,event.target===event.currentTarget)
target:最终目标元素,也就是最终触发事件的元素,而currentTarget:添加事件处理程序的绑定元素
当绑定事件处理程序的元素是父元素,事件最终触发在其子元素时,则currentTarget指向父元素,target指向该触发元素(子元素)。
EventUtil.addHandler(getDoc,"click",function(event){ //getDoc是一个储存父元素的变量
event=EventUtil.getEvent(event);
var target=EventUtil.getTarget(event);
alert(target.id); //为了知道target是哪个,处理很久的问题就出现在这里! //target指向最终发生触发事件的元素
switch(target.id){ //通过switch语句来获知点击哪个子元素,从而做出处理
case "indexLi": 语句;break; //因为功能某路径似乎有点运行不了,因此不提供case的处理语句
case "momentLi": 语句;break;
case "findMLi": console.log("fine");break; //为了测试是否运行成功
case "findPLi": ;break;
case "contactLi": ;break;
}
});
*想要知道target、event以及currentTarget分别指向什么,可以通过alert来得知。
以上代码的switch条件能否成功,需要根据HTML文档中的结构
<ul id="ulList">
<li id="indexLi">
首页
</li>
<li id="momentLi">摄圈子
</li>
<li id="findMLi">寻模特
</li>
<li id="findPLi">找摄影师
</li>
<li id="contactLi">联系我们
</li>
</ul>
如果结构如上,恭喜你成功运行。
倘若在<li>元素中添加了<a>标签,那么target.id则为undefine. 导致我一直困在这里,直到我用alert测试target以及currentTarget的结果后,发现是结构问题。
因此,事件委托中,想要target捕获到元素,只能存在于两层结构?(这是个问题,不是结论,望大佬们指点~)
当然,事件委托可以发生在多层结构,就是你点击了最内部的,它还是会执行alert();
//作者修改后,答:猪,才不是这样,经过作者本人重新测试后,之所以发生target.id为undefine,主要是因为自己没有把标签a的id填上,所以点击a的时候无法捕获target.id,导致无法执行case里面的语句。不过,要不是出错,我就不会对event和target了解得比较深。
补充:只要点击的元素是有id属性(为什么要有id?因为你switch条件是target.id)且case的条件中有执行该元素id字符串和处理方法即可。