JavaScript中on事件与addEventListener()

  • onclick()这种写法是DOM0级规范的写法,是所有的浏览器支持的,但是这种写法有不能同时绑定多个事件、使代码耦合在了一起的弊端。

  • addEventListener() 是DOM2标准中定义的方法,它可以控制是在事件捕获阶段或者是在冒泡阶段调用事件处理程序。只有支持DOM2级事件处理程序的浏览器才支持这个方法(IE9+)。

  • 原生addEventListener比jQuery中的on慢了60倍,本文中的on为原生的“on + 事件”。

addEventListener()on的区别要从事件侦听(Event Listeners)和内联事件(Inline Events)说起,下面以demo代码演示。

事件侦听(Event Listeners)

EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。

事件目标可以是一个文档上的元素 Document 本身,或者任何其他支持事件的对象 (比如 XMLHttpRequest)。

addEventListener语法

element.addEventListener(event, function, useCapture)

参数 event:表示监听事件类型的字符串(必须);

参数 function:一个实现了 EventListener 接口的对象,或者是一个函数(必须);

参数 useCapture:布尔值,指定事件是否在捕获或冒泡阶段执行(可选);

useCapture可能值(事件冒泡,稍后介绍):

  • true - 事件句柄在捕获阶段执行

  • false- 默认。事件句柄在冒泡阶段执行;

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
window.onload = function(){     
var box = document.getElementById("box");
box.addEventListener("click",function(){
console.log("我是box1");
})
box.addEventListener("click",function(){
console.log("我是box2");
})
}
//运行结果:
//我是box1
//我是box2

addEventListener特点

addEventListener 是 W3C DOM 规范中提供的注册事件监听器的方法。它的优点包括:

  • 允许给一个事件注册多个 listener。当存在其他的库时,使用 DHTML 库或者 Mozilla extensions 不会出现问题。
  • 提供了一种更精细的手段控制 listener 的触发阶段。(即可以选择捕获或者冒泡)。
  • 对任何 DOM 元素都是有效的,而不仅仅只对 HTML 元素有效。

内联事件(Inline Events)

由于内联事件是作为元素属性保存起来的,这些属性可以被覆盖,所以如果为同一个事件绑定了多个处理程序,那么最后一个处理程序会覆盖之前的程序。

1
2
3
4
5
6
7
8
9
10
11
12
window.onload = function(){     
var box = document.getElementById("box");
box.onclick = function(){
console.log("我是box1");
}
box.onclick = function(){
box.style.fontSize = "18px";
console.log("我是box2"); }
}
//运行结果:
//我是box2
//覆盖了前者

事件冒泡

点击div里a标签,触发了div的点击事件?这就是JS事件冒泡。JS事件冒泡分向上冒泡、向下冒泡;

好吧,有时候JS事件冒泡是我们想要的,有时候JS事件冒泡是讨厌的,Web前端开发者需根据项目实际情况处理。

向上冒泡

即:从子元素再到父元素冒泡,默认情况事件是按照事件冒泡的执行顺序进行的。

1
2
3
4
5
6
7
8
9
box.addEventListener("click",function(){     
console.log("box");
})
child.addEventListener("click",function(){
console.log("child");
})
//执行的结果:
//child
//box

如何做到从父元素向子元素的顺序冒泡呢?下面有请 addEventListener 闪亮登场添加true

向下冒泡

1
2
3
4
5
6
7
8
9
box.addEventListener("click",function(){     
console.log("box");
},true) //关键true
child.addEventListener("click",function(){
console.log("child");
})
//执行的结果:
//box
//child

addEventListener()方法中的第三个参数true是向下冒泡的关键,它规定事件句柄在捕获阶段执行。

浏览器兼容性

兼容性一直是程序员须警惕的,不过现在大可不必太过惧怕IE8及早期浏览器了,毕竟它们正在消亡!

简单封装,兼顾一下IE8及早期浏览器:

1
2
3
4
5
6
7
8
9
10
11
function addEvent(element, evnt, func){   
if (element.attachEvent){ // IE8及更低版本浏览器
return element.attachEvent('on'+evnt, func);
}
else{ // IE8+,或其它现代浏览器
return element.addEventListener(evnt, func, false);
}
}; //调用
addEvent(document.getElementById('element'),'click',function (){
// some code here
});