JavaScript中addEventListener/attachEvent 与内联事件

1.addEventListenerattachEvent

两者都是为元素注册事件,但是有区别:
        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,否则内联即可。

老外有较精辟的说法,点击这里



 

作者:Mr.Jimmy
出处:https://www.cnblogs.com/JHelius
联系:yanyangzhihuo@foxmail.com
如有疑问欢迎讨论,转载请注明出处

原文地址:https://www.cnblogs.com/JHelius/p/14318915.html