如果我们想要让某个DOM节点监听某个事件,最简单的方法就是使用on***方法。
如:我们想给button添加click事件,则
<script>
let btn = document.getElementById('btn');
btn.onclick = () =>{
alert(1);
}
</script>
如果这是我们想让那个btn监听另一个click事件,我们的做法一般是:
<script>
let btn = document.getElementById('btn');
btn.onclick = () =>{
alert(1);
}
btn.onclick = () =>{
alert(2);
}
</script>
但是问题来了,这时候我们发现点击btn只会弹出2,而不是先弹出1后弹出2,可以看出后面的监听事件会把前面的监听事件覆盖掉。所以这样的写法不能满足我们想让同一个DOM节点监听对个事件的需求。特别是当多人合作的时候,这样写也是非常危险的。因此我们应该避免on***监听的覆盖。
为了解决这个问题,我们可以使用attachEvent和addEventListener来替代on***监听事件。其中attachEvent是IE支持的方法,addEventListener是Firefox支持的方法。改写上述代码:
<script>
let btn = document.getElementById('btn');
btn.addEventListener('click',()=>{
alert(1);
})
btn.addEventListener('click',()=>{
alert(2);
})
btn.attachEvent('onclick',()=>{
alert(1);
})
btn.attachEvent('onclick',()=>{
alert(2);
})
</script>
这样便可以顺利的先弹出1后弹出2。可见attachEvent和addEventListener支持监听函数的叠加而不是覆盖。
接下来我们对上述代码进行封装,让其同时兼容IE和Firefox
<script>
onEvent = (obj,eventType,handler)=>{
obj = typeof obj =='string'?document.getElementById(obj):obj;
if(document.all){
obj.attachEvent(`on${eventType}`,handler);
}else{
obj.addEventListener(eventType,handler,false);
}
}
let btn = document.getElementById('btn');
onEvent(btn,'click',()=>{
alert(1);
})
onEvent(btn,'click',()=>{
alert(2);
})
</script>