js四种事件处理程序

随着W3C不断推进DOM事件模型和IE浏览器事件模型的历史变化,为了方便理解,程序员们中逐渐形成 四种事件处理程序 的概念划分。


提示:本文章内容最后修改时间为2017年04月,部分内容可能已经过时

在 JavaScript 中,通常分为四种事件处理程序:

  1. HTML事件处理程序
  2. DOM0事件处理程序
  3. DOM2事件处理程序
  4. IE事件处理程序

简单比较

HTML DOM0级 DOM2级 IE
代码形式 onclick="fun()" btn.onclick = fun(){} addEventListener() attachEvent()
作用域 扩展的作用域(全局) 元素的作用域 元素的作用域 全局作用域
触发阶段 冒泡阶段 冒泡/捕获阶段 冒泡阶段

HTML事件处理程序

在HTML的内联属性中添加事件处理。

<input type="button" value="Click" onclick="alert('Hello world!')" />

如上,可直接在onclick = ""里添加执行语句;也可如下,调用一个函数:

<input type="button" value="Click Me" onclick="showMessage()" />
<script type="text/javascript"> function showMessage(){ alert("Hello world!"); } </script>

关于它的执行作用域,比较特别,是不断扩展、修改的。可以访问到document以及元素本身的成员,就像访问局部变量一样。

优势:

显而易见的直观、方便,在某些情况下使用尤其便捷,比如统计某个按钮/链接的点击次数。

劣势

html和javascript耦合,当需要修改时,就会一下进行两处变动,可维护性是很差的。

在事件与调用函数分离时,如果调用函数较晚加载,就会出现点击事件而无响应的情况。

而在现今,比如Vue.js,框架本身能够补足这种写法的劣势,越来越多的主流JavaScript框架都是推崇这种内联属性的写法。

DOM0级事件处理程序

var element = document.getElementById("myBtn"); 
element.onclick = function(){
//操作
};

在事件的冒泡阶段被处理。

作用域是元素的作用域,换句话说,就是程序中的 this引用当前元素。

优势:

简单明晰,易于使用和理解。并且具有跨浏览器的优势。

劣势

因为直接赋值给对应属性,如果你在后面代码中再次为 element 绑定一个回调函数,会覆盖掉之前回调函数的内容,通俗来说就是很难实现多个绑定。

代码运行以前不会指定事件处理程序,因此如果这些代码在页面中位于按钮后面,就有可能在一段时间内没有响应。

虽然也可以用一些小技巧实现多个绑定,但还是推荐下面的DOM2级事件处理程序实现多个绑定

DOM0移除事件绑定

如果想要删除element的点击事件,将其置为null即可:

element.onclick = null

1级DOM–(为什么没有1级DOM)

DOM级别1于1998年10月1日成为W3C推荐标准。1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。在2级DOM中除了定义了一些DOM相关的操作之外还定义了一个事件模型 ,这个标准下的事件模型就是我们所说的2级DOM事件模型

DOM2级事件处理程序

var btn = document.getElementById('btn');
btn.addEventListener('click', function(){ 
  alert('你点击了这里');
}, false);

addEventListener是标准的事件处理程序,亦称为绑定事件监听,提供三个参数可供传递。(IE9+也支持addEventListener)

第三个参数是一个布尔值,true表示在捕获阶段被处理,fasle表示在冒泡阶段被处理,考虑到IE的兼容问题,一般不使用true

优势: 可以为一个元素添加多个事件处理程序。

DOM2移除事件监听

需要注意的是,绑定事件时的回调函数一般不能是匿名函数, 必须是一个声明的函数,因为解除事件绑定时需要传递这个回调函数的引用,才可以断开绑定。例如:

var fun = function() {
    // function logic
};

element.addEventListener('click', fun, false);
element.removeEventListener('click', fun, false);

IE事件处理程序

IE 浏览器就是特立独行,它对于事件的操作与标准有一些差异。不过 IE 浏览器现在也开始慢慢努力改造,让浏览器变得更加标准。

var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function(){ 
  alert("Clicked");
});

(IE事件处理程序:IE5到IE10支持,IE11就不再支持了。但是最好应用于IE5到IE8,因为IE9之后又略有变化)

实际上与addEventListener的使用十分相似。

区别在于,第二个参数传入的是onclick而并非click,且IE只支持在冒泡阶段进行程序处理,所以没有第三个参数布尔值的选择。 它的作用域为全局作用域,即this指向window。 此外,如果为同一个元素添加了两个事件处理程序,addEventListener会以添加的顺序依次执行事件处理,而attachEvent则相反。

如果要封装兼容attachEvent和addEventListener:因为attachEvent没有第三个参数,也就是说attachEvent只支持监听冒泡,所以为了统一,在使用addEventListener的时候第三参数传递 false。

IE移除事件监听

detachEvent(),用法与DOM2级的removeEventListener类似

总结

一般情况下为了最大限度发挥事件处理程序的作用,使用标准事件处理程序,即addEventListener,并且把第三个参数设为fasle;如果专门为了兼容IE,则使用attachEvent;如果是在编写一个小程序,为了简单快捷,可以使用DOM0级处理程序或者考虑HTML处理程序。

另外,依照上面的知识,如果想要得到跨浏览器的事件处理程序代码,请在网上自行搜索,找到一款合适自己的。

文章目录
  1. 简单比较
  2. HTML事件处理程序
  3. DOM0级事件处理程序
    1. DOM0移除事件绑定
  4. DOM2级事件处理程序
    1. DOM2移除事件监听
  5. IE事件处理程序
    1. IE移除事件监听
  6. 总结