1.DOM0
它可以在网页中直接定义监听函数,也可以通过 js 属性来指定监听函数。这种方式是所有浏览器都兼容的。
每个元素(包括 window 和 document )都有通常小写的事件处理程序属性,比如onclick 。只要把这个属性赋值为一个函数即可:
let btn = document.getElementById("myBtn");
btn.onclick = function() {
console.log("Clicked");
};
2.IE
IE实现了与DOM类似的方法,即 attachEvent() 和 detachEvent()。
这两个方法接收两个同样的参数:事件处理程序的名字和事件处理函数。因为IE8及更早版本只支持事件冒泡,所以使用attachEvent()添加的事件处理程序会添加到冒泡阶段。
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function() {
console.log("Clicked");
});
//注意, attachEvent() 的第一个参数是 "onclick" ,而不是DOM的 addEventListener()方法的 "click"
在IE中使用 attachEvent() 与使用DOM0方式的主要区别是事件处理程序的作用域。使用DOM0方式时,事件处理程序中的 this 值等于目标元素。而使用 attachEvent() 时,事件处理程序是在全局作用域中运行的,因此 this 等于 window 。
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function() {
console.log("Clicked");
});
btn.attachEvent("onclick", function() {
console.log("Hello world!");
});
这里的事件处理程序会以添加它们的顺序反向触发。换句话说,在点击例子中的按钮后,控制台中会先打印出 “Hello world!” ,然后再打印出 “Clicked” 。
像这样使用DOM0方式为事件处理程序赋值时,所赋函数被视为元素的方法。因此,事件处理程序会在元素的作用域中运行,即 this 等于元素。
通过将事件处理程序属性的值设置为 null ,可以移除通过DOM0方式添加的事件处理程序,如下面的例子所示:
btn.onclick = null; // 移除事件处理程序
3.DOM2
DOM2 Events为事件处理程序的赋值和移除定义了两个方法: addEventListener() 和removeEventListener() .
这两个方法暴露在所有DOM节点上,它们接收3个参数:事件名、事件处理函数和一个布尔值, true 表示在捕获阶段调用事件处理程序, false (默认值)表示在冒泡阶段调用事件处理程序。
let btn = document.getElementById("myBtn");
btn.addEventListener("click", () => {
console.log(this.id);
}, false);
与DOM0方式类似,这个事件处理程序同样在被附加到的元素的作用域中运行。使用DOM2方式的主要优势是可以为同一个事件添加多个事件处理程序。来看下面的例子:
let btn = document.getElementById("myBtn");
btn.addEventListener("click", () => {
console.log(this.id);
}, false);
btn.addEventListener("click", () => {
console.log("Hello world!");
}, false);
多个事件处理程序以添加顺序来触发,因此前面的代码会先打印元素ID,然后显示消息“Hello world!”。
大多数情况下,事件处理程序会被添加到事件流的冒泡阶段,主要原因是跨浏览器兼容性好。把事件处理程序注册到捕获阶段通常用于在事件到达其指定目标之前拦截事件。如果不需要拦截,则不要使用事件捕获。
参考:《javascript高级程序设计》