在 React 中处理路由变更,使其易于访问
(本文最初发表于Up Your A11y:在 React 中处理路由更改时的焦点)
任何客户端路由渲染都可能导致辅助技术用户感到困惑并丢失上下文信息。本文将简要探讨以下问题:
- 了解客户端渲染引起的一些焦点问题
- 实施一种简单的技术,为辅助技术用户恢复上下文,并确保更多人能够参与到您的内容中。
服务器端渲染与客户端渲染
简单来说,服务器端渲染是指当您导航到新路由时,服务器会被联系以请求显示页面,然后在浏览器中呈现一个全新的页面。
另一方面,客户端渲染意味着“examplesite.com”和“examplesite.com/page2”实际上是同一个页面(index.html),但客户端应用程序在运行时决定将哪些内容放入该单个页面中。
实际上,情况远比这复杂,尤其是在新的服务器端渲染技术出现之后。但理解 React 中焦点管理的关键在于,当用户点击链接跳转到应用中的另一个路由时,DOM 会在运行时被操作,并且当前页面的内容也会随之改变。用户实际上并没有“离开”当前页面。
这会引发一些无障碍访问方面的问题,其中之一是当路线发生变化时焦点的处理方式。
快速比较一下简单的链接点击
想象一下以下场景:作为屏幕阅读器用户,你阅读到同一个网页应用中指向另一个页面的链接。你使用键盘命令点击该链接。你期望发生什么?
在“服务器端渲染”领域,会发生以下情况:
- 屏幕阅读器提示您已点击链接
- 浏览器中加载了一个全新的页面。
- 页面焦点已重置
- 新页面已发布
但我们都知道,像 React 这样的客户端渲染不会打开新页面。如果没有显式处理焦点,更可能发生的事件链是:
- 屏幕阅读器提示您已点击链接
- 新内容已获取并显示在用户界面中。
- 屏幕阅读器不会向您播报任何有关新内容的信息。
- 即使首页上的链接已不可见,人们的注意力仍然集中在该链接上。
试想一下,对于视力障碍用户来说,这会多么令人困惑。他们怎么知道在这个新页面上该从哪里开始浏览呢?
用户当前的注意力可能集中在页面中间,与你希望他们阅读的主要内容相去甚远。当他们尝试开始阅读新内容时,可能无法立即意识到其价值,或者会因为缺乏上下文而感到沮丧。无论哪种情况,他们都很可能会放弃并离开你的应用。
潜在解决方案
解决这个问题有几种方法,所有方法都涉及在新内容加载时手动操作页面焦点。那么问题来了:当新“页面”加载时,我们应该把焦点放在哪里?
最近,GatsbyJS 发表了一篇有趣的文章,总结了一些用户对这些技术的测试结果。我建议完整阅读他们的文章,但先剧透一下:
调查发现,聚焦于标题是最佳体验方式,因为它既能节省时间,又能清晰地说明发生了什么。
一个非常简单的解决方案
继续上面简单的链接点击示例——Gatsby 用户测试中发现最理想的行为是确保以下事件顺序:
- 你点击链接,屏幕阅读器确认你已按下该按钮。
- 新内容已获取并显示在用户界面中。
- 新内容加载完毕后,焦点会立即落到新内容的“h1”元素上。
- 屏幕阅读器会朗读“h1”标签的内容。
这有助于从两个关键方面恢复上下文:
- “h1”标题很可能位于页面顶部,因此键盘焦点位置会重置到更常规的位置,而不是可能漂浮在页面中间。
- “h1”标签应该已经包含了新页面的最相关描述,以及用户可以在该页面上找到的内容(毕竟它是页面的主要标题!)。立即显示该标签可以让用户快速了解新内容。
实施该解决方案
实现这种行为非常简单,只需要三个基本步骤:
- 在制表顺序的开头插入 h1 元素,并为其添加引用。
- 在 componentDidMount() 中使用您创建的 ref 聚焦 h1 元素。
- 禁用 h1 元素的默认焦点高亮显示,以防止焦点信息仅对屏幕阅读器可见。
一个非常基础的“可聚焦标题”组件示例实现:
class FocusableHeader extends React.Component {
headingRef = React.createRef()
componentDidMount() {
this.headingRef.current.focus()
}
render() {
return (
<h1
ref={this.headingRef}
className="focusable-header"
tabIndex="-1" >
I'm a focusable header!
</h1>
)
}
}
export default FocusableHeader
以及用于禁用此特定类型页眉的可见焦点样式的相关 CSS:
.focusable-header:focus {
outline: none;
}
就这样!
只需几个简单的步骤,即可处理路由更改的重点,并且您的内容可以轻松地被更广泛的用户群体所消费。
但请记住,将项目插入 Tab 键顺序和禁用焦点高亮显示必须极其谨慎和仔细考虑;我只是根据针对此特定用例的用户研究才提出此建议。
如果您想查看包含应用内路线更改示例的此帖子版本,以便您可以测试初始方法和示例解决方案,请前往Up Your A11y,在那里您可以找到它!
你觉得这篇文章有用吗?如果可以的话,请我喝杯咖啡,这样我才能继续创作内容哦🙂
文章来源:https://dev.to/s_aitchison/handling-route-changes-in-react-accessibility-44fn