DOM0、DOM1、DOM2、DOM3级事件的区别 - 之 DOM2事件

DOM2级事件处理程序:

要在按钮上为click事件添加处理程序,像下面这样:

var btn = document.getElementById("mybtn");
btn.addEventListener("click",function(){
    alert(this.id)
},false)

该事件在冒泡阶段被触发(最后一个参数false)。使用DOM2事件,也是在元素的作用域内运行。而且,可以给元素绑定多个监听事件:

var btn = document.getElementById("mybtn");
btn.addEventListener("click",function(){
    alert(this.id)
})
btn.addEventListener("click",function(){
    alert("Hello World!")
})

结果会依次显示。
使用addEventListener()只能通过removeEventListener()删除触发。所以如果给一个匿名函数,就没法删除该事件了。

var btn = document.getElementById("mybtn");
btn.addEventListener("click",function(){
    alert(this.id)
})
btn.removeEventListener("click",function(){
    alert(this.id) // 没什么用
})

给函数起一个名字,给一个指针。

var btn = document.getElementById("mybtn");
var handler = function(){
    alert(this.id)
}
btn.addEventListener("click",handler,false)
btn.removeEventListener("click",handler,false)//有效!

大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段。这样可以最大限度地兼容各种浏览器。如果不是特别需要,不建议在事件捕获阶段就注册事件处理程序。
由于IE8及以下版本只支持冒泡事件,所以IE自己的类似方法是:attachEvent()和detachEvent()。现在都2021年了,就不展开了。只说两点:
    □:接收同样的两个参数。事件名称和对应处理函数。
    □:而且IE中使用attachEvent()与DOM0和DOM2级区别是处理程序的作用域。比如this等于window的问题。

var btn = document.getElementById("mybtn");
btn.attachEvent("onclick",function(){
    alert(this === window); // true
})

所以现在就引出了这个问题,跨浏览器的事件能力监测。它的职责是视情况分别使用DOM0级方法、DOM2级方法或IE方法来添加事件。
    □:创建一个EventUtil()的对象。
    □:创建一个addHandler()方法,接收三个参数:目标元素、事件名称、事件处理函数。

var EventUtil = {
    addHandler : function(element,type,handler){
        if(element.addEventListener){
            element.addEventListener(type,handler,false)
        }else if(element.attachEvent){
            element.attachEvent("on" + type,handler)
        }else{
            element["on" + type] = handler;
        };
    },
    removeHandler : function(element,type,handler){
        if(element.removeEventListener){
            element.removeEventListener(type,handler,false)
        }else if(element.detachEvent){
            element.detachEvent("on" + type,handler)
        }else{
            element["on" + type] = null;
        }
    }
};

解释:这两个方法都会先监测是否存在DOM2级方法。如果存在DOM2级方法,就是用该方:传入事件类型、事件处理程序函数和第三个参数false(表示冒泡阶段)。如果存在的是IE的方法,则采取IE方案。为了IE8及更早版本,需要加上“on”前缀。最后一种可能就是使用DOM0级方法(在现在浏览器中,应该不会执行到这里),而此时,使用方括号语法将属性名指定为事件处理程序,或者设置为null,卸载事件。
如何使用?

var btn = document.getElementById("mybtn");
var handler = function(){
    alert("clicked!")
}
//使用此函数
EventUtil.addHandler(btn,"click",handler);
//卸载此函数
EventUtil.removeHandler(btn,"click",handler);

虽然addHandler()和removeHandler()没有考虑IE的作用域问题,不过,够用了。

跳转到【事件流】