1.addEventListener与attachEvent
两者都是为元素注册事件,但是有区别:
i.addEventLstener符合W3C标准,因而大部分浏览器会支持
attachEvent是IE专有,在IE9以下浏览器中得使用他,IE9+已经转而支持addEventLstener,放弃了attachEvent
ii.addEventListener的eventType参数不需要加"on"
attachEvent的eventType必须包含“on”(如“onclick”)
i.addEventLstener符合W3C标准,因而大部分浏览器会支持
attachEvent是IE专有,在IE9以下浏览器中得使用他,IE9+已经转而支持addEventLstener,放弃了attachEvent
ii.addEventListener的eventType参数不需要加"on"
attachEvent的eventType必须包含“on”(如“onclick”)
iii.addEventListener拥有userCapture参数,当该参数为true时执行事件捕获,若为false执行事件冒泡(
冒泡与捕获具体参考这里)
attachEvent参数只有两个(eventType,function),没有userCapture参数
iiii:addEventListener的标准书写方式为
element.addEventListener('eventType',function,userCapture);
attachEvent的标准书写方式为
element.attachEvent('on'+'eventType',function);
//attachEvent没有userCapture参数,那是否支持捕获,他的触发事件顺序是怎样?笔者暂时没有深刻研究,之后会在此补充
由于两者的差异,我们就需要一个兼容性写法,可以在任何浏览器下注册事件,写法如下:
function RegisterEventListener(ele,eventType,func,capture){
if(ele.addEventListener){
ele.addEventListener(eventType,func,capture);
}
else if(ele.attachEvent){
ele.attachEvent("on"+eventType,func);
}
}
2.removeEventListener与detachEvent
removeEventListener标准写法为element.removeEventListener('eventType',function,userCapture)
detachEvent标准写法为element.detachEvent('on'+'eventType',function)
两者都去除元素对事件的绑定,差异与上文的addEventLstener与attachEvent一样,他们的兼容写法如下:
function RemoveEventListener(ele,eventType,func,capture){
if(ele.addEventListener){
ele.removeEventListener(eventType,func,capture);
}
else if(ele.attachEvent){
ele.detachEvent("on"+eventType,func);
}
}
3.内联事件
注册事件的写法除了上面两个,还有我们最常用的οnclick=“xxx()”(称之为内联事件),这样注册事件的形式就有3种:
1.addEventLstener
2.attachEvent
3.内联事件写法
前两种实际上是相同的函数在不同浏览器的写法而已,而内联事件则不同,我们来说说前两者与内联事件的区别,我们书写代码如下,为div_2加上内联事件:
<html>
<head>
<script>
function init(){
document.getElementById("div_1").addEventListener("click",function (){alert(this.id);},true);
document.getElementById("div_2").addEventListener("click",function (){alert(this.id);},true);
document.getElementById("div_3").addEventListener("click",function (){alert(this.id);},true);
}
</script>
</head>
<body onload="init()">
<div id="div_1" style="background-color:#FFF200; 150px;height:150px" > div_1 <br/>
<div id="div_2" style="background-color:#EFE4B0; 120px;height:120px; margin-left:15px;" onclick="alert(2);" > div_2 <br/>
<div id="div_3" style="background-color:#B5E61D; 90px;height:90px; margin-left:15px; " > div_3<br/><br/>
click me!
</div>
</div>
</div>
</body>
</html>
此时弹框为:div_1=>div_2=>div_3=>2
这样我们猜测内联写法等同于userCapture=false(事件冒泡时触发)的addeventListener写法。我们继续测试,在上面基础上修改init()函数:
function init(){
document.getElementById("div_1").addEventListener("click",function (){alert(this.id);},false);
document.getElementById("div_2").addEventListener("click",function (){alert(this.id);},false);
document.getElementById("div_3").addEventListener("click",function (){alert(this.id);},false);
}
此时弹框:div_3=>2=>div_2=>div_1
我们猜测没错,内联确实与usercapture=false的情况相符。同时有个细节,div_2绑定了两个click事件(一个内联事件,一个addEventListener),但是先执行的内联事件。这是由于页面加载时,在init()执行之前就注册的内联事件。
因此,这时代码等同于:
document.getElementById("div_2").addEventListener("click",function (){alert(2);},false);
document.getElementById("div_1").addEventListener("click",function (){alert(this.id);},false);
document.getElementById("div_2").addEventListener("click",function (){alert(this.id);},false);
document.getElementById("div_3").addEventListener("click",function (){alert(this.id);},false);
所以结论就是:内联事件是等同于userCapture=false的addEventListener写法,只是他在页面初始化时最先注册,所以执行顺序早于同元素usercapture=false的注册事件。
4.什么时候用addEventListener,什么时候用内联事件
上面的例子我们不难发现,利用addEventListener可以对一个元素注册多个同类(eventType)事件。(上面的div_2就有两个click事件,所以触发了两次)
而内联事件的写法很显然只能最多有一个,但是他的写法确实比较简便,也容易理解。因此,当你需要对一个元素注册多个事件,并需要考虑捕捉(usercapture)时,使用addEventListener,否则内联即可。
老外有较精辟的说法,点击这里。