JavaScript 事件 - 事件处理程序

108 阅读2分钟

一、HTML 事件处理程序

将 JS 代码字符串赋值给 HTML 事件属性。

用法:

<input type="button" value="Click me" onclick="alert('Clicked)" />

<!-- or -->

<script>
    function showMessage() {
        console.log('Hello world!');
    }
</script>

<input type="button" value="Click me" onclick="showMessage()" />

注意,这种方式应考虑 HTML 转义问题;可以使用 DOM0 级事件处理程序的移除方式。

作用域:

在全局作用域中运行。但能直接拿到事件对象 event,尤其是在表单元素中的应用。

缺点:

  1. 可能存在 HTML 事件被触发,但事件处理程序还未定义的情况。如,上面示例中,若 script 标签定义在页面底部且远远晚于 input 标签,就极可能出现这种情况。此时,应使用 try catch 来规避错误。
  2. 不同浏览器下可能会出现作用域链不同的情况。
  3. HTML 代码与 JS 代码耦合紧密,修改不方便。

二、DOM0 级事件处理程序

将一个函数赋值给一个事件处理程序属性。

用法:

// 获取元素引用
var btn = document.getElementById("myBtn");

// 添加事件
btn.onclick = function() {
    console.log("Hello world!");
};

// 移除事件
btn.onclick = null;

在事件流的冒泡阶段执行。

作用域:

在元素的作用域中运行。换句话说,事件处理程序中的 this 引用当前元素。

console.log(this.id); // "myBtn"

缺点:

只能添加一个事件处理程序。

三、DOM2 级事件处理程序

用法:

// 获取元素引用
var btn = document.getElementById("myBtn");

// 定义事件
var handler = function() {
    console.log("Hello world");
}

// 添加事件
btn.addEventListener("click", handler, false);

// 移除事件
btn.removeEventListener("click", handler, false);

addEventListener/removeEventListener 均接收三个参数:事件名、事件处理函数和一个布尔值。

  • 事件名不带 on 前缀,这是与其他所不同的。
  • 第三个参数若为 true,则在捕获阶段处理,反之在冒泡阶段处理。

可分多次添加多个事件,触发时按照添加的顺序依次执行。

不建议添加匿名的事件处理函数,因为无法移除。

作用域:

在元素的作用域中运行。换句话说,事件处理程序中的 this 引用当前元素。

console.log(this.id); // "myBtn"

四、IE 事件处理程序

与 DOM2 级事件处理程序非常相似。

用法:

// 获取元素引用
var btn = document.getElementById("myBtn");

// 定义事件
var handler = function() {
    console.log("Hello world");
}

// 添加事件
btn.attachEvent("onclick", handler);

// 移除事件
btn.detachEvent("onclick", handler);

attachEvent/detachEvent 均接收两个参数:事件名、事件处理函数。

可分多次添加多个事件,触发时按照与添加的顺序相反的顺序依次执行。

不建议添加匿名的事件处理函数,因为无法移除。

由于 IE8 及之前只支持事件冒泡,所以 attachEvent 添加的事件处理程序在事件流的冒泡阶段执行。

作用域:

在全局作用域中运行。换句话说,事件处理程序中的 this 等于 window。

console.log(this === window); // true