JavaScript 高级事件注册:W3C 与微软模型对比

作者:流萤时间:2026-10-25 03:16:14浏览:516

本文详细解析 JavaScript 中 W3C 标准与微软 IE 特有的事件注册模型。重点介绍 W3C 的 addEventListener 方法,包括多监听器支持、冒泡与捕获阶段控制及 this 指向;同时对比微软的 attachEvent 模型,指出其缺乏捕获机制和 this 指向 window 的缺陷,帮助开发者实现跨浏览器兼容的事件处理。

W3C 事件注册模型详解

W3C 组织与微软均致力于开发各自的事件注册模型,以取代 Netscape 提出的传统模型。尽管我对微软的模型持保留态度,但 W3C 的方案整体表现良好,仅鼠标定位方面存在些许争议。目前,仅有少数浏览器支持这些新模型。


W3C


W3C 的 DOM 事件规范注意到了传统模式中存在的问题,并为在一个元素上绑定多个事件处理程序提供了有效的解决方案。


W3C 事件注册模型的核心在于 addEventListener() 方法。该方法接收三个参数:事件类型、要执行的函数以及一个布尔值(true 或 false),后者将在后续章节解释。若要将熟悉的 doSomething() 函数注册到元素的 onclick 事件,可采用以下写法:


element.addEventListener('click',doSomething,false)


这种模型的优势在于可以添加任意数量的监听器。沿用之前传统模式的示例,我们可以这样编写:


element.addEventListener('click',startDragDrop,false)


element.addEventListener('click',spyOnUser,false)


当用户点击该元素时,两个事件处理程序都会执行。需要注意的是,W3C 标准并未规定事件执行的先后顺序,因此不能假设 startDragDrop() 一定在 spyOnUser() 之前执行。


移除事件处理程序同样简单,只需使用 removeEventListener() 即可。例如:


element.removeEventListener('click',spyOnUser,false)


这将移除第二个事件处理程序,而第一个保持不变。这种程序设计非常优雅,彻底解决了传统模式下的诸多问题。



匿名函数与参数控制

匿名函数


在 W3C 模式下,你依然可以使用匿名函数:


代码如下:

 
element.addEventListener('click',function () {
this.style.backgroundColor = '#cc0000'
},false)

true 或者 false


true 或 false 是 addEventListener 的最后一个参数,用于指定函数是在捕获阶段还是冒泡阶段执行。如果不确定,建议使用 false(冒泡阶段)。


this


在 JavaScript 中,this 关键字通常指代函数的所有者。如果 this 指向触发事件的 HTML 元素,那么一切都将变得简单,你可以轻松执行多种操作。


不幸的是,虽然 this 功能强大,但若不明确其运作机制,使用起来仍具有一定难度。关于这一点,我在其他章节有详细讨论。


在 W3C 模型下,this 的行为与传统模式一致:它表示当前正在处理事件的 HTML 元素。


代码如下:

 
element.addEventListener('click',doSomething,false);
another_element.addEventListener('click',doSomething,false);
function doSomething() {
this.style.backgroundColor = '#cc0000';
} 

若将 doSomething() 注册到任意 HTML 元素的 click 事件上,当用户点击时,该元素的背景色将变为红色。



哪个事件处理程序被注册了呢?


目前,W3C 事件注册模式存在一个缺陷:你无法直接得知某个元素注册了哪些事件处理程序。在传统模式下,你可以:


alert(element.onclick)


通过查看返回值,可以知道哪些函数已注册,若返回 undefined 则表示未注册任何函数。直到最近的 DOM Level 3 事件规范,W3C 才添加了 eventListenerList 来存储已注册的事件处理程序。由于该规范较新,支持它的浏览器寥寥无几。然而,这一问题已有解决方案。


值得庆幸的是,removeEventListener() 不会因未注册某个事件而返回错误,因此你可以放心使用 removeEventListener()。


微软事件注册模型及其缺陷

微软


微软也提供了一种事件注册模型。它与 W3C 模型相似,但存在一个严重缺陷。


将一个事件处理程序 attach 到元素:


element.attachEvent('onclick',doSomething)


或者,你需要两个事件处理程序:


element.attachEvent('onclick',startDragDrop)


element.attachEvent('onclick',spyOnUser)


移除一个也非常简单:


element.detachEvent('onclick',spyOnUser)



缺陷


与 W3C 模型相比,微软模型存在两个严重问题:


第一,事件总是冒泡,不存在捕获阶段。


第二,事件处理程序是被引用的而非拷贝,导致 this 关键字始终指向 window,从而失去其原有作用。


这两个问题的后果是,如果事件发生冒泡,你将无法确定是哪个元素在处理事件。我将在后续的事件顺序章节中详细解释这一点。


此外,微软的标准仅被 IE 浏览器支持,无法用于跨浏览器开发。即使你仅为 Windows 浏览器编写脚本,也最好避免使用,因为冒泡问题会导致情况变得复杂难控。


继续


如果你想继续学习,请参阅下一章。


原文地址:http://www.quirksmode.org/js/events_advanced.html


第一次翻译,请大家多多包涵。我的 twitter:@rehawk

作者最新文章