级别: 初级 崔 晓玲, 软件工程师, IBM 马 兵东, 软件工程师, IBM
2009 年 10 月 29 日 随着 Web 2.0 应用的广泛应用,如何让屏幕读取软件的用户能够随心所欲的操作 Web 2.0 应用程序是目前 Web 2.0 应用的开发人员所面临的一个问题。本文主要介绍了屏幕读取软件的基本功能,以及针对这些功能的 Web 应用开发要点,希望可以帮助 Web2.0 应用开发人员掌握支持屏幕读取软件的技巧。
辅助功能 (Accessibility) 是帮助残疾人更有效地使用计算机的专用程序和设备,它有很多类型,例如适用于低视力人群的屏幕放大器,通过声音命令操作电脑的语音输入工具等等。而其中最重要的类型之一是适用于盲人的屏幕读取软件。屏幕读取软件是专为盲人或视力有障碍的人设计的屏幕朗读软件。用户可以通过功能键和数字键盘的切换,就能够随心所欲地查找和处理文件,对网页进行导航浏览。因此对屏幕读取软件支持的好坏是衡量一个 Web 应用程序提供辅助功能优劣的一个重要标准。现在 Web2.0 技术的应用已经像雨后春笋一样遍布了整个互联网,同时随着 Ajax 和 JavaScript 的广泛应用,越来越多的静态 Web 页面转变为充满交互的 Web2.0 应用。而 Accessibility 的问题也随之而来。比如亚马逊的钻石搜索(Amazon diamond search)就给人们展示了一个使用 Ajax 来创造高级交互接口的伟大案例,它使用了拖拽条来控制筛选标准,然后根据用户选择的标准自动呈现数据给用户,亚马逊的这个应用为很多用户提供了非常棒的用户体验,但是对于那些使用屏幕读取软件的用户来说,它根本不可用。因此,如何开发支持屏幕读取软件的应用是每个 Web2.0 应用开发人员需要面对的一个问题。
为了支持屏幕读取软件,Web2.0 应用开发需要从以下几个方面考虑:支持读取页面信息功能,支持页面导航功能,支持图片识别功能,支持表格识别功能和支持 Forms 表单识别功能。目前 Dojo 向 Web2.0 开发者和设计者提供了一个强大的 JavaScript 工具集用以快速开发健壮的 Ajax 应用。本文将结合 JavaScript 和 Dojo,详细阐述如何开发支持屏幕读取软件的应用。
支持读取页面信息功能
屏幕读取软件的基本功能就是读取页面信息。而屏幕读取软件阅读网页的能力主要来自网页中 HTML 元素给出的相应信息,比如链接 a 标记的 href 和 title 属性。屏幕读取软件通过 href 属性来识别链接标记。例如下列 javascript 脚本片断:
清单 1. 含有链接的 javascript 片断 .
var link = document.createElement("a");
link.innerHTML = “Go Back to RQM Home”;
link.title = “Go Back to RQM Home”;
link.onclick = dojo.hitch(this, "showHomePage");
link.id = "return-rqm-home-link";
|
相应的 css 片断:
清单 2. 支持链接的 css 片断 .
#return-rqm-home-link
{
color: rgb(48, 158, 158) !important;
margin-top: 5px;
margin-left: 10px;
font-size: 8pt;
}
|
程序员动态生成链接标签,并且使用 css 来控制链接的颜色,用 onclick 方法控制链接的行为。但由于没有 href 属性,屏幕读取软件并不能识别 link 是一个链接标记。因此需要为它设置 href 属性,同时不影响链接的行为:
清单 3.为链接添加标识 .
link.setAttribute("href", "javascript:{}");
|
支持页面导航功能
视力正常的用户可以很容易的分辨整个页面的布局。例如,他们可以忽视标题或者列表,从而直接获取主要内容区域的信息。如果页面组织结构合理,上述的大多数方法同样适用于屏幕读取软件。
Skip to main content
当导航条出现在页面上方或者左方时,使用屏幕读取软件的用户必需听完导航条上所有的 link 或者 button,才能获取页面主体部分的信息。当一个 Web 应用中的所有页面都保持这种统一布局风格时,用户每切换一次页面,都要重新浏览一遍导航条中的内容。这对视力正常的用户来说,可以忽视这些 link 直接阅读,而屏幕读取软件则借助 “Skip to main content”链接略过导航条的所有内容,直接将焦点设置到页面的主体部分。
例如下面的 One-page 的 Web 应用由四部分构成:上部全局任务条,左部导航条,右部帮助区域以及中间主体部分:
图 1. One-page Web 应用示例图
整个页面的 html 结构为:
清单 4.页面 html 结构 .
<div class="com-ibm-rqm-web-home" dojoAttachPoint="_homepageArea">
<div id="rqm-global-task-bar" dojoAttachPoint="_globalTaskBarArea"></div>
<div id="rqm-right-help-bar" dojoAttachPoint="_rightHelpBarArea"></div>
<div id="rqm-left-navigation-bar" dojoAttachPoint="_leftNavigationBarArea"></div>
<div id="content-area" dojoAttachPoint="_contentArea">
</div>
|
其中,发生变化的是中间主体部分 _contentArea,因此需要在页面顶部添加”Skip to main content”链接,使得屏幕读取软件可以直接跳转到主体部分:
清单 5. 添加 Skip to main content 链接 .
<div style="left:-200px; position:absolute; display: inline;">
<a id="_mainContentHref" name="_mainContentHref"
dojoAttachPoint="_mainContentHref" href=”#content-area”>
Skip to main content
</a>
</div>
|
其中, style="left:-200px; position: absolute; display: inline;"是为了在视图中隐藏此链接,目的是不影响页面的视觉效果。这样,屏幕读取软件用户在使用左方导航条切换页面时,能够快速的定位到主体内容。
Skip to Navigation
当一个页面由若干个结构风格相似的 section 组成时,程序开发人员需要为每个 section 添加一个链接,这样屏幕读取软件用户就可以方便的跳转到他所关心的 section 中。
例如下图页面由 General Info, Hardware, Operating System, Software 四个 section 组成:
图 2. 多 section 的 Web 应用示例图
Web 应用开发人员需要在当前页面最上部添加四个链接:
清单 6. 添加 skip to navigation 链接 .
<div style="position: absolute; left: -3000px; width: 500px;">
<a dojoattachevent="onclick:_onSkipActivation, onfocus:_onFocusItem" href="#">
Skip To General Info
</a>
<a dojoattachevent="onclick:_onSkipActivation, onfocus:_onFocusItem" href="#">
Skip To Hardware
</a>
<a dojoattachevent="onclick:_onSkipActivation, onfocus:_onFocusItem" href="#">
Skip To Operating System
</a>
<a dojoattachevent="onclick:_onSkipActivation, onfocus:_onFocusItem" href="#">
Skip To Software
</a>
</div>
|
同样的,这四个链接不会影响页面视图。当屏幕读取软件用户触发链接时,就会调用 onclick 事件,程序自动地将焦点设置到相应 section 的标题上,从而用户可以方便的浏览此 section 中的内容。
支持图片识别功能
如果不加特殊处理,屏幕读取软件将忽略 Web 应用中的图片信息,因此为每个有意义的图片,尤其是链接或者按钮等活动图片提供文本格式的替换信息,是开发支持屏幕读取软件 Web 应用的首要原则。这些文本信息必须是有意义的,并且能为图片提供简单的描述,用户可以根据图片替换信息,借助屏幕读取软件识别图片。对于不重要或者冗余的图片,将图片替换信息设置为空,屏幕读取软件就会忽略这个图片。图片替换信息并不仅仅适用于有视力障碍的用户,它同样适用于那些只支持文本的浏览器,如手机浏览器。
为 img 元素添加 alt 属性
例如,下图左方图片为用户提供了类型信息:
图 3. Web 应用中的图片
这个图片的代码为:
清单 7. 图片的代码 .
//Html 代码:
<img src="rtlm_machine.jpg" alt="${labelGroup}" width=”150” height=”175”/>
//javascript 代码:
this.labelGroup = Constance.getMessage(“labelGroup”);
|
值得注意的是,对于使用鼠标的用户来说,如果鼠标放到图片上,alt 的内容将会显示在屏幕上。因此对于一个支持全球化的 Web 应用来说,不能简单的在 html 代码里设置 alt 属性值,否则 Web 应用将不会根据浏览器 locale 信息而选择相应的 alt 翻译。例如如果在 html 代码里直接设置 alt=”The type is group”,一个中国用户看到的图片信息将会是英文字符串。这里我们通过在 javascript 中给 labelGroup 赋值的方法来避免 globalization 问题。
为活动图片添加文本信息
Web 应用为了视觉美观,会将按钮或者链接等元素以图片的形式显示出来。例如,下图右上角的两个图片分别是“添加用户”和“删除用户” 按钮。
图 4. Web 应用中的活动图片
其中“添加用户”按钮的 javascript 实现为:
清单 8. 为图片添加文本信息 .
// 构造 button 元素
var addButton = document.createElement("button");
var img = document.createElement("img");
img.src = “Add_User.jpg”;
addButton.appendChild(img);
addButton.onclick = function() {
this.addUser();
}
|
//为 button元素添加文字信息
//设置 button元素的 name属性,其值为相应的文字信息
addButton.name = Constance.getMessage(“addUser”);
|
用户可以通过屏幕读取软件获取此按钮信息:Add User Button。
支持表格识别功能
Web 应用通过表格表示一组数据之间的关系。当用户遇到一个表格时,他必须可以理解表格的用处,并且能获取表格中的所有的元素信息。这对于视力正常的用户来说是非常容易的,但是那些需要借助屏幕读取软件获取信息的用户却很容易在大量的数据面前丢失方向。这就需要在 html 中提供适当的 markup,使得屏幕读取软件能够很好的识别表格中的数据以及其所表达的相应信息。
例如下图中的表格,我们通过以下四步使得屏幕读取软件能很好的识别其中的信息。
图 5. Web 应用中的表格
-
通过 <th> 标记指示行 / 列表头:创建易于访问的数据表格的第一步就是指明行 / 列表头。开发人员可以通过定义 <th> 标记明确的指示行 / 列表头。
-
将数据单元与适当的表头关联起来:有两种方式将数据单元和其相应的表头关联起来:
-
scope 属性 : scope 属性作用于标头元素中,值为 row 或者 col,分别表示该元素是行头或者列头。
-
headers 和 id 属性 : id 属性作用于表头元素,headers 属性作用于数据单元,与其相应的标头元素的 id 对应。它们的作用与 scope 相同,用以区分表头和数据。值得注意的是,这两个属性使用起来比较复杂,因此通常用于复杂表格,即表格中的一个数据单元与两个以上的表头相关联。
-
设置 table 元素的 summary 属性:summary 为用户提供表格的描述信息,屏幕读取软件可以读出 summary,同时 summary 的值是不可见的,因此不会对页面产生影响。例如,上图表格中列出当前所需的 Requirements,视力正常的用户可以通过阅读左上方的标题和表格上方的说明来了解表格的作用。而屏幕读取软件则可以根据 summary 属性,帮助用户直接了解表格中所含信息的结构或目的。
-
避免使用多于二层行 / 列表头的表格:一些屏幕读取软件不能识别多层行
/列表头的表格,因此 Web应用的开发人员要尽量使用简单的,一维或者二维表格 。
支持 Forms 表单识别功能
Form 在 Web 页面中用于各种各样的交互,例如 Form 允许用户选择和购买商品,填写调查表,注册用户等。屏幕读取软件应该能够访问到 Form 元素并且明确每个 Form 元素的目的。为了达到这个目标,屏幕读取软件需要考虑两个因素:正确定位每个 Form 元素的文本描述标签;正确定位 Form 中需要用户交互的区域。因此 Web 应用开发人员应该满足以下几方面的要求:
用 <label> 元素将 Form 与其描述外在的关联起来。用 <legend> 元素为一组 radio buttons 或者 checkboxes 提供标签
例如,下图是一个需要用户输入名字的 Input 元素:
图 6. Web 应用中的 Input Form
其代码为:
清单 9. 为 Input 添加 label.
//html 代码:
<label for="name">${labelName}</label>
<input id="name" dojoAttachPoint="_ name" value="" type="text/>
//javascript 代码:
this.labelName = Constance.getMessages(“labelName”);
|
值得注意的是,<label> 元素中,for 属性的值与 input 元素的 id 值是一一对应的。
对于 radio buttons 或者 checkboxes,借助 <fieldset> 和 <legend> 元素将一组 Form 元素相互关联起来,并提供描述信息。例如:
图 7. Web 应用中的 radio button
清单 10.为 radio button 添加 legend.
<fieldset>
<legend>Choose your favorite ice cream flavor</legend>
<input type="radio" name="chocolate" id="choc" />
<label for="choc">Chocolate</label>
<input type="radio" name="vanilla" id="vanilla" />
...
</fieldset>
|
在不能使用 <label> 元素的情况下,通过 title 属性定义 Form 的描述信息
例如一个搜索栏,允许用户输入检索信息,其代码为:
清单 11. 为无 label 的 Form 元素添加描述信息
//html 代码:
<input title="${labelTitle}" type="text"/>
//javascript 代码:
this.labelTitle = Constance.getMessages(“labelTitle”);
|
对于特殊元素,例如 dojo 中定义的 Form 元素需要特殊处理
通常,dojo 中所定义的 Form 元素,例如 dijit.form.CheckBox 或者 dijit.form.RadioButton,都是自动生成 id 属性,不能直接由用户定义。而为了将 Form 元素与 label 元素关联起来,Web 开发人员需要为 label 元素设置 for 属性,使之与 Form 的 id 值保持一致。我们可以通过以下方法满足 dojo 定义的 Form 元素对屏幕读取软件的支持:
清单 12. 特殊 Form 元素处理
// html代码:
//在html中声明Form和label元素,不设置id和for属性。
//注意,开发人员可以通过dojoType指定当前元素的类型:
<input value="labelShowAdapter" dojoAttachPoint="labelShowAdapter"
name="adapter" dojoType="dijit.form.CheckBox"/>
<label dojoAttachPoint="labelShowAdapterLabel"> Show Addapter</label>
//javascript代码:
// 在相应的javascript中设置label元素的for属性:
this.labelShowAdapterLabel.setAttribute("for", this.labelShowAdapter.id);
|
如果一个页面上有多个类似的 Form 元素,需要用 title 属性详细加以说明
图 8. 多个 Input Form 示例图
如上图所示,同一个页面上有两个 input form,都是用来搜索表格内容。由于这两个 input 元素是针对不同的表格,如果它们的 title 都是”search table content”,用户将不能区分每个 input 元素的具体作用,从而影响屏幕读取软件的使用效率。因此 Web 应用开发人员要对每一个 Form 元素都加以无歧义的说明。
总结
虽然目前的 Web 应用开发人员已经能够通过编程手段比较好的支持屏幕读取软件,但是在具体的使用中,我们也发现屏幕读取软件在对视觉布局,数据表格等方面的处理还有一些不如意的地方。例如屏幕读取软件不能很好的描述 Web 应用的视觉布局。视力正常的用户可以很快的了解到一个页面的组织结构,迅速定位到核心内容。而屏幕读取软件只能线性的访问页面,不能直接跳过广告或者导航条等无关内容。类似的,对于结构非常复杂的数据表格来说,屏幕读取软件如何能够帮助用户清楚地了解他所关心的数据将是一个值得研究的课题。但是无论如何目前已有足够多的方法开发出支持屏幕读取软件的 Web 应用,我们有理由期待屏幕读取软件对 Web 应用的支持会更好。
参考资料
作者简介  | |  | 崔晓玲是 IBM CSDL ECM Widget 中的成员之一,曾经从事 Rational Quality Management 项目的 Web UI 开发工作。她对 Web development 有一定的心得体会。 |
 | |  | 马兵东,就职于 IBM CSDL ETI,目前从事软件生命周期方面的开发工作,长期从事 Java EE 开发工作,对 Web 2.0 以及开源社区也有浓厚兴趣 |
对本文的评价
|