5.2 通过事件处理改变文档的行为
事件处理可能是JavaScript提供给以用户界面为中心的开发人员最好的东西了。它也是最容易搞混的一个JavaScript主题,并不是因为它复杂,而是因为不同的浏览器实现事件处理的方式不同。我会很快给你解释事件是什么;展示一个成熟的、好用的处理事件的方法;接下来会讲一个W3C推荐的新方法。最后,你会学到如何调整与W3C兼容的方法,让不支持它的浏览器也可以理解你的脚本。
事件可以是各种各样的事情,例如:
l 初始化的加载和网页文档的呈现;
l 图片的加载;
l 用户单击一个按钮;
l 用户按一个键;
l 用户把鼠标移动到某个元素上。
注解 可以把事件处理想象成一个移动探测器或门铃装置——如果有人移动到门跟前,灯就会打开;如果有人按下门铃的按钮,电路就会闭合,铃声装置就会被触发并发出声音。同样的原理,当用户把鼠标放到一个链接上去触发一个函数或当用户单击这个链接去触发另一个函数的时候,你也可以检测到。
可以用好几种方式应用事件处理,使你的脚本知道正在发生什么。最直接的方式就是在HTML中使用内置的事件:
![]()
一个更巧妙的方式在前面的章节中已经提到了:通过一个类或ID标识一个对象,然后在脚本中设置事件处理程序。最简单也是支持最广泛的方式是直接用属性为对象应用事件处理程序:

注解 注意没有必要去检查ID为info的元素,因为这个函数只能被它调用。
以这种方式触发事件有几个问题:
l 没有把这个元素传给函数;需要再次查找这个对象。
l 只能一次指派一个函数。
l 你的脚本以独占的方式劫持了这个元素的事件——其他脚本的方法试图在这个对象上使用其他事件的时候就不再起作用了。
除非你已定义triggerLink作为一个全局变量或对象属性,不然函数infoWindow()需要在使用它前找出触发的元素。

这个问题与“关联一个事件的多个函数”的问题可以通过应用一个调用真实函数的匿名函数来解决,它同样也允许你通过关键字this来传送当前的对象:

第三个问题仍然没有解决。在网页文档中的最后一个脚本,会覆盖其他脚本的事件触发,这意味着它不能和其他的脚本一起工作。因此你需要一种不覆盖其他脚本的指定事件处理的方式。在文档被加载后你需要调用几个不同函数的时候,这个尤为重要。
Simon Willison(http://simon.incutio.com/)为此建立了一个解决办法,它使用下面的这个方法来进行事件处理:

如果使用这个工具函数把函数添加到网页中,就不会覆盖其他被网页的load事件调用的函数。这在过去和现在都是一个很大的进步。
据我所知,前面的方法在所有支持JavaScript的浏览器中都好用。在特殊情况下,如果你不得不支持Mac平台上的IE 5,那么还有很多事情要做。新的浏览器支持改进了的事件模型,它可以清楚区分事件处理的不同方面。
5.2.1 W3C标准兼容的事件
注解 本节中的例子需要在DOM-2兼容的浏览器上执行。推荐使用Mozilla Firefox的1.5版本。IE 6不是DOM-2兼容的浏览器,这些例子在它上面不会正常工作。本节会讲解W3C是如何定义事件的以及它的工作原理。然后,我们会扩展这个方法以在IE以及其他不支持的浏览器上执行。
W3C中的DOM-2和即将发布的DOM-3规范对于事件处理的方法有所不同。首先,它们详细定义了处理事件时要用到的几个概念:
l 事件(event)是发生的动作,例如,click。
l 事件处理程序(event handler),例如onclick,在DOM-1中是注册事件的地方。
l 在DOM-2中,这点略有不同——你处理的是事件目标和事件监听器:
n 事件目标(event target)是事件发生的地方,大多数情况下就是一个HTML元素。
n 事件监听器(event listener)是一个函数,它用来处理事件。
l DOM-3引入了事件捕捉(event capturing)的概念,现在还没有浏览器支持它。如果想学习这些东西,可以查看W3C规范(http://www.w3.org/TR/DOM-Level-3-Events/events.html);这里我不会涉及事件捕捉,因为它现在还不是可用的JavaScript的一部分。
1.应用事件
可以通过addEventListener()方法来应用一个事件。这个方法有3个参数:一个是事件,它是一个不带“on”前缀的字符串,一个是事件监听器函数的名字(不带括号),还有一个是Boolean值,叫useCapture,它定义了是否使用事件捕捉。就目前而言,把useCapture设置为false是比较安全的。
如果想通过addEventListener()把函数infoWindow()应用到链接上,那么可以使用下面的代码:
![]()
如果需要添加一个悬停特效,在鼠标移动到链接上时调用highlight()函数,在鼠标离开链接时调用unhighlight()函数,可以多加两行代码:

2.检查触发的事件名称、地方和方式
从开发便利性的角度来看,好像又回到了以前的地方:你必须再次在函数infoWindow()中查找元素来读取href。的确是这样的,然而,通过使用addEventListener,标准兼容的浏览器会给你提供事件对象(event object),可以通过一个叫e的参数来读出它。
你以前可能见到过e,并想知道它到底是什么,是否应该相信一个不知道从哪儿来的e。应用事件时,使用一个没有传递的参数刚开始会使你很困惑,但你一旦学会了事件对象,就再也不会回去使用onevent属性了。事件对象拥有许多你可以在事件监听器函数中使用的属性。
l target:触发事件的元素。
l type:被触发的事件(例如,click)。
l button:被按下的鼠标按钮。0代表左按钮,1代表中间按钮,2表示右按钮。
l keyCode/data/charCode:被按下的键的字符编码。W3C规范使用data;可是,它并没有获得广泛的支持。相反大多数浏览器都使用charCode,而keyCode是IE的实现。幸好所有的现代浏览器都能理解keyCode,这意味着你现在可以使用它,直到data在用户代理中获得更广泛的支持。
l shiftKey/ctrlKey/altKey:一个布尔值——如果Shift、Ctrl或Alt键(分别地)被按下则返回true。
可供使用的完整属性列表取决于你所监听的事件。可以在DOM-2规范中查找所有的属性列表:http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Registration-interfaces。
使用Event对象,可以很容易地使用一个函数来处理几个事件:

对于这3种事件,可以使用同样的函数并检查它们的事件类型:

也可以通过检查事件目标的nodeName来检查事件发生所在的元素。再次提醒你一下,必须使用toLowerCase()以避免跨浏览器平台的问题:

3.停止事件传播
指派事件与使用事件监听器截取它们也意味着你需要注意两个问题:一个是许多事件都有默认的动作——举个例子,click可能使浏览器打开一个链接或提交一个表单,而keyup则可能添加一个字符到表单域中。
另外一个问题叫做事件冒泡(event bubbling),它主要意味着当一个事件发生在一个元素上的时候,它也发生在这个元素的所有父元素上。
● 事件冒泡
回到新闻列表的HTML标记:
exampleEventBubble.html

如果为列表中的链接指派一个mouseover事件,悬停在它们上面也会触发其他的事件监听,它们可能是在段落上、列表项上、列表上,以及节点树直到文档的主体上的所有其他元素。通过下面这个例子,你会明白如何把事件监听器附加到指向适当函数的每个对象上:
eventBubble.js


现在在它们被单击的时候,所有的列表项都会触发liTest()方法,所有的段落会触发pTest()方法,所有的链接会触发aTest()方法。
可是,如果单击段落,你会得到两个警告:
![]()
可以使用e.stopPropagation()方法来阻止这种情况的发生,它可以确保只有应用到链接上的事件监听器会得到这个事件。如果把pTest()方法修改为下面的样子:
stopPropagation.js——在exampleStopPropagation.html中使用

输出会是:
![]()
事件冒泡事实上问题并不大,因为你不会常把不同的监听器指派给内嵌元素而不指派给它们的父元素。如果想学习更多有关事件冒泡以及某个事件发生后事件监听器发生顺序的内容,可以参考Peter-Paul Koch写过的一篇非常优秀的文章,参见http://www.quirksmode.org/js/events_order.html。
● 阻止默认的动作
你可能还会遇到的一些其他问题是,某些元素的事件拥有自己默认的动作。例如,链接会载入另一个文档。你可能不希望它发生,因此必须在执行你的事件监听器函数后停止默认的动作。
在DOM-1事件处理程序模型中,可以通过在被调用的函数中返回一个false来实现:

如果单击前面例子中的任何一个链接,它们都会加载链接的网页文档。可以使用DOM-2的preventDefault()方法来覆盖它。我们把它添加到aTest方法中测试一下:
preventDefault.js——在examplePreventDefault.html中使用

现在单击这个链接就只会显示警告窗口:
![]()
链接的页面不会被打开,而且你会停留在原页面,对链接数据进行其他处理。
例如,你可以开始的时候只显示大标题,并在单击它们时展开要显示的内容。首先,你的样式表中还需要一些类来处理这些改变。
listItemCollapse.css(摘录)

折叠元素的脚本并不复杂,复杂的是使用我们讲过的所有处理对象的事件:
newsItemCollapse.js



结果是可以单击的新闻标题,单击它们时会显示相关的新闻摘要。“more”链接并没有受影响,它在被单击的时候会把完整的新闻文章发送给用户(参见图5-6)。

图5-6 通过单击标题显示新闻项
我们一步一步来看所有的脚本。在定义了CSS类属性和检查了必需的元素后,开始循环遍历所有的列表项,获取第一个链接(它是标题中的一个链接),并为click、mouseover和mouseout指派事件监听程序。click事件应该触发newshl.toggleNews()方法,而mouseout和mouseover应该触发newshl.hover()方法。
newsItemCollapse.js(摘录)

可以通过在段落上应用隐藏类来隐藏列表项中的所有段落:
newsItemCollapse.js(摘录)

toggleNews()方法通过读取事件对象的目标来获取当前的元素。这个目标是链接,它意味着如果你想访问列表项,需要访问两次父节点。
newsItemCollapse.js(摘录)
![]()
读取列表项中的第一个段落并检查它是否已经有指派给它的隐藏类。如果已经有指派的隐藏类,定义变量action为remove;否则定义action为add。设置另一个叫做sectionAction的变量,把它定义为与action有相同的选项但对立的变量。
newsItemCollapse.js(摘录)
![]()
循环遍历所有的段落,根据action决定是删除hideClass还是添加它。对于section和currentclass使用同样的处理,但是这次使用sectionAction。这样就可以有效地控制段落的可见性和标题的样式。
newsItemCollapse.js(摘录)

通过调用preventDefault()阻止最初单击的链接被打开,并调用stopPropagation()方法禁止事件冒泡。
newsItemCollapse.js(摘录)
![]()
hover方法通过parentNode获取列表项并检查用来调用这个方法的事件类型。如果事件是mouseout,定义动作为remove;否则的话定义为add。然后应用这个CSS类或从列表项中删除这个类。
newsItemCollapse.js(摘录)

最后,给window对象添加一个事件监听程序,它会在窗口完成加载后触发newshl.init()方法。
newsItemCollapse.js(摘录)
![]()
现在你知道了在DOM-2兼容的浏览器中如何处理单击后的变化了。现在该考虑一下其他的浏览器,确保这些功能也可以得到支持。
5.2.2 修正事件以适应W3C不兼容的浏览器
现在你已了解了事件处理的原理(在许多新的浏览器中得到了支持,希望在这些不兼容W3C的浏览器上也好用),我们来看看这些违反统一标准的浏览器并学习一下如何来处理它们。
注解 这些帮助方法已经包含在DOMhelp.js里了;如果你想不使用DOMhelp而直接使用这些方法,那么可以在源代码中找到它们。
它们其中之一就是IE 6,考虑到它的年龄和它要扮演的角色(浏览器和操作系统文件管理器),实际上这也是可理解的。IE有它自己的事件模型,因此等价的标准方法不仅命名不同而且行为表现也不同。
IE中使用了方法attachEvent()来代替addEventListener();IE还在window.event中保留了一个全局的事件对象来代替为每个监听程序传递事件对象。
一位名叫Scott Andrew的开发人员提出了一个更方便的函数,叫做addEvent(),它解决了添加事件方式不同的问题:
![]()

这个函数比addEventListener()多用了一个参数,这个参数代表元素本身。它检查是否支持addEventListener(),而且它如果可以用W3C兼容的方式绑定事件的话就返回true。
否则的话,它会检查是否支持attachEvent()(意味着使用的是IE),并试图用attachEvent绑定事件。注意对于事件attachEvent()不需要“on”前缀。对于既不支持addEventListener()也不支持attachEvent()的浏览器(如Mac平台上的IE),这个函数则把DOM-1属性指向了函数。在Mac平台的IE上,这样做会覆盖附加到这个元素上的其他事件,但至少它可以用了。
注解 关于如何改进addEvent()一直存在争议——例如,为了支持保留使用this来发送当前对象的选择——到目前为止已出现了许多灵活的解决方案。但由于它们每一个都存在不同的缺点,所以这里就不做详细介绍了,但如果你特别感兴趣,可以到网站quirksmode.org (http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html)的addEvent()编码大赛页面上查看相关内容。
由于IE使用了一个全局事件,所以你不能依赖传送给监听程序的事件对象,需要编写一个不同的函数来获得被激活的元素。问题变得更加混乱了,因为window.event的属性和W3C事件对象中的任何一个都有所不同:
l 在IE中,target被srcElement取代了。
l button返回的值也不同。在W3C模型中,0表示左按钮,1表示中间按钮,2表示右按钮;可是IE左按钮返回1,右按钮返回2,中间按钮返回4。它同样也返回3,但是是在左按钮和右按钮同时被按下的时候,并且在三个按钮同时被按下的时候返回7。
为了适应这些变化,可以使用下面的这个函数:

或更简单一些,可以使用三元运算符:

Safari有一个令人讨厌的bug(或特性——这个无法确定):如果你单击一个链接,它不把这个链接作为目标,而是把包含在链接里的文本节点作为目标。一个变通的办法就是检查这个元素的节点名是否真的是一个链接:

阻止默认的动作和事件冒泡也需要使其适应不同的浏览器实现。
l stopPropagation()不是IE中的一个方法,而是窗口事件的一个叫做cancelBubble的属性。
l preventDefault()也不是IE中的一个方法,而是一个叫做returnValue的属性。
这意味着你不得不编写自己的stopBubble()和stopDefault()方法:

注解 Safari支持stopPropagation()方法,但是使用它却什么也做不了。这意味着它不会阻止事件继续冒泡,因此对于此没有很好的解决办法。希望这个问题会在未来的版本中得到解决。

由于一般情况下都需要阻止这两件事情发生,所以把它们集中放到一个函数中可能会更有意义:

使用这些帮助方法可以使你很容易处理事件和跨浏览器的问题,但是有一个例外:
Safari可以理解这个preventDefault()方法,但是它没有实现它应该完成的功能。因此,如果你给链接添加一个事件处理,并在监听程序的方法中调用cancelClick(),这个链接依然会被打开。
对于Safari这个问题的解决方法是,使用老版本的onevent语法另外添加一个哑函数来阻止这个链接被打开。你很快就会在脚本中看到这个修改。再看一下折叠标题的例子,把与DOM-2兼容的方法和属性替换为跨浏览器平台的帮助方法:
xBrowserListItemCollapse.js ——在exampleXBrowserListItemCollapse.html中使用



注解 hl.onclick = DOMhelp.safariClickFix;可以简化为hl.onclick =function(){return false;};可是,一旦Safari开发组把这个问题排上了日程,搜索和替换这个修改会更容易些。
可以单击的标题现在在所有现代的浏览器上都可以工作了;然而,看上去可以使这个脚本更简化一些。现在的例子作了许多循环,实际上并不真的有必要。可以不用在列表项中单独地隐藏所有的段落,只要给列表项添加一个类,让CSS引擎来隐藏所有的段落就会更容易:
listItemCollapseShorter.css(摘录)——在exampleListItemCollapseShorter.html中使用

使用这种方式可以去除init()方法中的遍历所有段落的内部循环,并且使用一行代码来替换它,这行代码把hide类应用到了列表项上,如下:
listItemCollapseShorter.js(摘录)——在exampleListItemCollapseShorter.html中使用


下一个修改是在toggleNews()方法中。在那里可以使用一个简单的if条件来代替循环,它会检查当前的类是否被应用到列表项上,如果应用了,则使用hide来代替current;如果没有,则使用current来代替hide,这样就可以显示或隐藏列表项中的所有段落了。
listItemCollapseShorter.js(摘录)——在exampleListItemCollapseShorter.html中使用

剩下的部分仍然是一样的:
listItemCollapseShorter.js(摘录)——在exampleListItemCollapseShorter.html中使用

5.2.3 永不停止优化
分析你的代码以判断哪些地方可以优化,这种工作应该永远不要停止,即使在你热烈编码并创建更复杂功能的时候也不例外。
往后退一步,分析一下你需要解决的问题,并重新评估一下已完成的东西,有时候比只是不断地编写代码更有好处。在这个例子中,优化就在于把隐藏元素留给了CSS的层叠,而不是循环遍历所有的元素并逐一地隐藏它们。
当你再看一遍以前创建的代码的时候,下面的几个要点需要你记住:
l 任何可以避免嵌套循环的思想都是好的。
l 主要对象的属性能很好地存储对几个方法都重要的信息——例如,站点导航中被激活的元素。
l 如果你发现自己有很多代码重复了,那么可以创建一个新的方法来完成这个任务——如果将来需要修改这些代码,你只需要在一个地方修改就可以了。
l 不要过多使用节点树来访问。如果许多元素需要知道其他的元素,一旦查出了它就把它存到一个属性中。这样可以使代码更简短,因为类似contentSection的东西要比elm.parentNode.parentNode.nextSibling更简短一些。
l 一个很长的if和else语句列表作为一个switch/case块处理可能会更好一些。
l 如果一些代码将来很可能要修改,如Safari的stopPropagation(),那么最好把它们放到自己的方法中。下次你看到这些代码并发现这些表面上看起来没什么用处的方法,你会记得它们是要干什么的。
l 不要过分依赖于HTML。它一直是首先要修改的东西(尤其是在CMS中)。
5.2.4 页面加载问题及其解决方案
当开发人员开始大量使用CSS的时候,很快就会碰见许多令人厌烦的浏览器bug。其中之一就是无样式内容瞬间(flash of unstyled content),也就是大家所知道的FOUC(http://www.bluerobot. com/web/css/fouc.asp)。在应用样式之前,显示的网页会有一小段时间没有样式表。
我们现在面临着和JavaScript增强的网页同样的问题。如果加载折叠新闻项的例子,你会看到所有的新闻需要一个瞬间展开。这个瞬间是文档和它的所有依赖内容如图片和第三方内容完成加载过程需要的时间。
这个问题使追求完美效果的开发人员郁闷了很长一段时间,因为在页面和所有被包含的媒体如图片被加载的时候会触发onload事件。不过,许多聪明的DOM程序员集中智慧解决了这个问题。
Dean Edwards(高科技领域中需要记住的一个名字)编写了一个脚本,可以在页面完成加载所有的内容元素前执行代码,这样就可以实现没有跳跃的平滑界面。可以在http://dean. edwards.name/weblog/2005/09/busted/上测试他的解决方案。.
这种解决办法的问题是它严重依赖于特定的浏览器代码而且在Safari和Opera上不起作用。这个方法未来可能会修改,所以要不时访问一下Dean的网站。
还有一个不同的解决方案,它可以被所有启用了JavaScript的浏览器支持,但在结构、表现和行为的分离方面做得不够好。它通过document.write()把隐藏元素必需的CSS写入了文档的HEAD中。如果你想把这个应用到新闻标题的例子中,所要做的就是在HTML文档的头部添加这个列表项的段落样式。
exampleListItemCollapseNoFlash.html(摘录)

注解 样式标签的连接使用是非常有必要的,可以避免验证程序提示HTML不合法。
这两个版本的解决方案都是切实可行的,但都有点美中不足,到目前为止,我没有看到其他有关这个问题的更好解决方案。
5.2.5 读取和过滤键盘输入
最常用的Web事件可能要算是click了,因为它有所有元素都支持的优点而且可以同时用键盘和鼠标触发,如果这个正在处理的元素可以通过键盘访问到的话。
然而,并没有什么因素阻止我们在JavaScript中使用keyup或keypress处理器来检查键盘的输入。前者是W3C标准;后者不在标准中,它发生在keydown和keyup之后,但是在浏览器中它得到了广泛的支持。
我们来编写一个如何读取和使用键盘输入脚本,它会检查在一个表单框中输入的数据是否全部是数字。在第2章中,你已检查过输入的内容,并把它转换为了数字,但是这次你要在输入的时候检查它而不是在表单提交之后。如果用户输入了一个非数字字符,脚本程序应该设置表单的提交按钮为不可用并给出错误信息提示。
来看一个只有一个输入框的简单HTML表单:
exampleKeyChecking.html


在应用了下面的脚本后,浏览器会检查用户输入的内容,并在输入的内容不是一个数字的时候,给出一个错误提示信息,设置提交按钮为不可用,如图5-7所示。

图5-7 在按键的时候检查输入的内容
keyChecking.js



首先,你需要定义一些属性,如一个错误信息、一个表示是否已显示了错误信息的布尔值以及一个应用到错误信息上的类。需要对必需的元素进行检查,并附加一个指向checkKey()方法的keyup事件。
keyChecking.js(摘录)

checkKey方法会判断是否使用了window.event或事件对象并且会以适当的方式读取keyCode。
keyChecking.js(摘录)

然后它获得这个元素(在这里我们通过getElementById()来获得,虽然你也可以使用DOMhelp.getTarget(e)轻松获得,但是没有必要使用复杂的,够用就可以了),并且检查错误属性是否为true。如果它为true,那么就已经存在一个可见的错误信息并且提交按钮是不可用的。在这种情况下,你需要删除错误信息,设置error属性为false,并且设置提交按钮可用(它是input元素的下一个兄弟节点——这里使用closestSibling()可以确保它是一个按钮而不是一个换行)。
keyChecking.js(摘录)

需要确定按下的键不是0~9的任何一个阿拉伯数字——也就是说,它的ASCII码不在48~57之间。
提示 可以在任一的ASCII码表中获得每个键的值,例如,在网站 http://www.whatasciicode.com/上。
如果这个键不是一个数字键,那么删除域值中输入的最后一个键,并创建一个错误信息。创建一个新的span元素、添加应用errorClass类、添加错误信息、把它作为一个新的子节点追加到文本输入框的父节点上并且设置表单的按钮为不可用。剩下的最后一件事情就是在页面完成加载的时候启动voucherCheck.init()方法。
keyChecking.js(摘录)


注解 通常对于每一个keyup事件检查域中输入的内容是否为一个数字已经足够了,但是这个例子给你示范了使用键盘事件的威力。
如果想读取使用了Shift、Ctrl或Alt的组合键,那么需要在你的事件监听方法中检查事件属性shiftKey、ctrlKey或altKey:
![]()
5.2.6 事件处理的危险
使用这些函数,可以监听用户引起的任何一个事件并作出反应。可以使导航条表现为翻转效果而不是链接的单击,你可以添加只在网页上有效的快捷键,而且你可以使任何元素都对鼠标的移动作出反应。
使用事件处理全部的内容,如导航内容、用户旅行线路以及使用表单和用户进行交互是非常吸引人的。问题在于,这到底是一件好事还是坏事?
这是因人而异的,有人可能会以为拖放式界面会是最好的,但是对于不能使用鼠标的用户怎么办?可以通过绑定事件使文档中的所有元素都是可交互的;可是,并不是所有的用户代理都会允许访问者不用鼠标就可以访问到元素。一个可以单击的标题对于键盘用户不是可用的,但是带有嵌入链接的标题是可以使用的,因为用户可以使用tab键来访问链接,但是不能使用它来访问标题。
基本的可访问性指南和法律都强调,如果需要使用DOM编程和HTML创建自己的富界面,你需要保留输入设备的独立性。
一个拖放式界面并没有什么过错,只要你也允许使用键盘访问它就可以。因为你不能依赖于JavaScript是可用的,所以对于可拖放的元素你需要真正的链接,它可以使用click事件,甚至键盘访问。
键盘事件处理也是一个问题。虽然大多数浏览器都支持keypress(在W3C规范中没有提到它,它们更喜欢使用keyup),但你永远无法知道你要指派给一个元素的快捷键对于用户电脑上的另一款软件是否是必需的。
键盘的访问是操作系统必不可少的一部分,需要使用某种组合键的访问者在工作中就会劫持你的这些组合键。因此灵活的网络应用程序都使得键盘快捷键是可以选择的甚至是可被用户定制的。
当使用accesskey属性的时候,在HTML中也会发生同样的问题。这个属性会告诉浏览器当定义在属性值中的键被按下的时候激活元素(在IE和Mozilla中要和Alt键一起使用,而在其他的一些浏览器中则使用其他的组合键)。实质上,这样就是添加一个事件并指派一个事件监听程序,从而设置元素的焦点或者打开元素的默认动作。一直以来,对这些属性使用数字键一直是非常常见的而且被认为是安全的,除非有一个用户,他的名字中有特殊的字符而且需要使用Alt和这些字符的ASCII码来输入名字。
总而言之,富HTML和JavaScript界面还在研究中,可以在网站http://www.mozilla.org/access/ dhtml/上看一看,而且可以使用IBM和Mozilla开发的丰富控件。






