JavaScript 在我们创建的几乎所有内容中都发挥着重要作用,从较小的动态组件到在 JavaScript 框架(例如 React 或 Angular)上运行的完整产品,不一而足。
这种使用(或过度使用)JavaScript 的做法带来了许多令人担忧的趋势,例如由于代码量过多、使用非语义 HTML 元素以及通过 JavaScript 注入 HTML 和 CSS 而导致的加载时间过长。您可能不确定无障碍功能在这些方面发挥着怎样的作用。
JavaScript 可能会对您网站的无障碍功能产生巨大影响。在本单元中,我们将分享一些由 JavaScript 增强的无障碍功能常规模式,以及针对使用 JavaScript 框架时出现的无障碍问题的解决方案。
触发事件
借助 JavaScript 事件,用户可以与 Web 内容互动并执行特定操作。许多用户(例如屏幕阅读器用户、精细运动技能障碍人士、没有鼠标或触控板的用户等)依靠键盘支持与网络进行互动。请务必为 JavaScript 操作添加键盘支持,因为这会影响所有这些用户。
我们来看看点击事件。
如果在 <button>
或 <a>
等语义 HTML 元素上使用 onClick()
事件,则自然会同时包含鼠标和键盘功能。不过,如果将 onClick()
事件添加到非语义元素(例如通用 <div>
),系统不会自动应用键盘功能。
<div role="button" tabindex="0" onclick="doAction()">Click me!</div>
<button onclick="doAction()">Click me!</button>
如需预览此对比,请前往 CodePen。
如果将非语义元素用作触发器事件,则必须添加 keydown/keyup 事件来检测 Enter 键或空格键的按下操作。人们常常会忘记向非语义元素添加触发器事件。遗憾的是,如果忘记了,结果就是组件只能通过鼠标访问。仅使用键盘的用户将无法执行关联的操作。
网页标题
正如我们在“文档”模块中所学,网页标题对屏幕阅读器用户至关重要。它会告知用户他们当前所在的页面以及他们是否已转到新页面。
如果您使用 JavaScript 框架,则需要考虑如何处理网页标题。对于从单个 index.html
文件加载的单页应用 (SPA),这一点尤为重要,因为转换或路由(页面更改)不涉及重新加载页面。默认情况下,每次用户在 SPA 中加载新页面时,标题都不会更改。
对于 SPA,可以手动或使用帮助程序包添加 document.title 值(具体取决于 JavaScript 框架)。向屏幕阅读器用户读出更新后的网页标题可能需要额外的工作,但好消息是,您可以使用动态内容等选项。
动态内容
JavaScript 最强大的功能之一是能够向网页上的任何元素添加 HTML 和 CSS。开发者可以根据用户的操作或行为创建动态应用。
假设您需要在用户登录您的网站或应用时向他们发送消息。您希望该消息在白色背景中脱颖而出,并传达以下消息:“您现在已登录。”
您可以使用 innerHTML
元素来设置内容:
document.querySelector("#banner").innerHTML = '<p>You are now signed in</p>';
您可以使用 setAttribute
以类似的方式应用 CSS:
document.querySelector("#banner").setAttribute("style", "border-color:#0000ff;");
能力越大,责任也就越大。遗憾的是,在历史上,HTML 和 CSS 的 JavaScript 注入功能一直被滥用来创建无法访问的内容。下面列出了一些常见的滥用行为:
可能的滥用 | 正确使用 |
---|---|
渲染大量非语义 HTML | 渲染较小的语义 HTML 片段 |
不允许辅助技术识别动态内容 | 使用 setTimeout() 时间延迟,让用户能够听到完整的消息 |
动态为 onFocus() 应用样式属性 |
在 CSS 样式表中,对相关元素使用 :focus |
应用内嵌样式可能会导致无法正确读取用户样式表 | 将样式保留在 CSS 文件中,以保持主题的一致性 |
创建会降低网站整体性能的非常大的 JavaScript 文件 | 减少使用 JavaScript。您或许可以在 CSS 中执行类似的功能(例如动画或固定导航栏),这些功能的解析速度更快,性能也更出色 |
对于 CSS,请切换 CSS 类,而不是添加内嵌样式,因为这样可以实现可重用性和简单性。在网页上使用隐藏内容和切换类来隐藏和显示动态 HTML 的内容。如果您需要使用 JavaScript 向网页动态添加内容,请确保内容简单明了,并且易于访问。
焦点管理
在“键盘焦点”模块中,我们介绍了焦点顺序和指示器样式。焦点管理是指了解何时何地应捕获焦点,以及何时不应捕获焦点。
焦点管理对仅使用键盘的用户至关重要。
组件级
如果组件的焦点未得到妥善管理,您可以创建键盘陷阱。 当仅使用键盘的用户卡在某个组件中,或者焦点未在应有的位置时,就会发生键盘陷阱。
用户最常遇到焦点管理问题的模式之一是在模态组件中。当仅使用键盘的用户遇到模态窗口时,用户应能够在模态窗口的可操作元素之间按 Tab 键切换,但绝不应允许用户在未明确关闭模态窗口的情况下离开模态窗口。若要正确捕获此焦点,JavaScript 至关重要。
网页级
当用户从一个网页导航到另一个网页时,也必须保持焦点。在 SPA 中尤其如此,因为在 SPA 中不会刷新浏览器,并且所有内容都会动态更改。每当用户点击链接前往应用中的另一个页面时,焦点都会保持在原来的位置,或者可能会完全移到其他位置。
在页面之间转换(或路由)时,开发团队必须决定页面加载时焦点会移至何处。
实现此目的的方法有多种:
- 将焦点放在包含
aria-live
通知的主容器上。 - 将焦点重新放置在跳转到主要内容的链接上。
- 将焦点移至新页面的顶级标题。
您决定将重点放在哪里,取决于您使用的框架以及您希望向用户提供的内容。它可能取决于上下文或操作。
状态管理
JavaScript 对无障碍功能至关重要的另一个方面是状态管理,或者将组件或网页的当前视觉状态转发给使用辅助技术的弱视、盲人或盲聋用户。
通常,组件或网页的状态是通过 ARIA 属性进行管理的,如 ARIA 和 HTML 模块中所介绍。我们来了解一些最常见的 ARIA 属性类型,这些属性可帮助管理元素的状态。
组件级
在向用户转达组件相关信息时,需要考虑许多 ARIA 状态,具体取决于网页内容和用户需要的信息。
例如,您可以使用 aria-expanded
属性告知用户下拉菜单或列表是展开还是收起状态。
或者,您也可以使用 aria-pressed
来指示按钮已被按下。
在应用 ARIA 属性时,请务必选择性地使用。仔细考虑用户体验流程,了解应向用户传达哪些关键信息。
网页级
开发者通常使用一个名为 ARIA 实时区域的视觉隐藏区域,向辅助技术 (AT) 用户播报屏幕上的更改和提醒消息。此区域可与 JavaScript 搭配使用,以便通知用户网页发生的动态更改,而无需重新加载整个网页。
长期以来,由于 JavaScript 的动态特性,在 aria-live
和警报区域中播报内容一直很困难。异步将内容添加到 DOM 会使 AT 难以获取地区信息并进行播报。为了正确读取内容,实时区域或提醒区域必须在加载时位于 DOM 中,然后才能动态换出文本。
好消息是,如果您使用的是 JavaScript 框架,几乎所有这些框架都提供了“实时播报员”软件包,可为您完成所有工作,并且完全可访问。您无需担心创建实时区域并处理上一部分中所述的问题。
以下是一些常见 JavaScript 框架的实时软件包:
- React:react-aria-live 和 react-a11y-announcer
- Angular:
LiveAnnouncer
- Vue:vue-a11y-utils
现代 JavaScript 是一种强大的语言,可让 Web 开发者构建强大的 Web 应用。这有时会导致过度工程化,进而导致不可访问的模式。通过遵循本单元中的 JavaScript 模式和提示,您可以让所有用户都能更方便地使用您的应用。
检查您的理解情况
测试您对 JavaScript 的知识
使用 JavaScript 更改元素样式的最佳方式是什么?
所有 JavaScript 操作是否都支持键盘用户?