在 React.js 上使用键盘导航时,屏幕阅读器无法读取页面 [英] Screen Reader not reading the page when navigated with keyboard on React.js

查看:21
本文介绍了在 React.js 上使用键盘导航时,屏幕阅读器无法读取页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户通过单击链接"组件导航到新页面时,屏幕阅读器会以正确的顺序完美地读取新页面.如果用户通过按 Enter 或空格键选择新页面,浏览器仍会导航到正确的页面,但屏幕阅读器不会读取页面内容.

新页面导航的代码如下所示:

 <链接到={`/event/${eventId}`} 组件={CardActionArea}><卡片媒体className={classes.media}/><CardContent className={classes.cardContent}>...一些信息..</卡片内容></链接></卡片>

我试图通过创建一个 keyDownEvent 来解决这个问题,但没有用:

 const elementRef = React.createRef();const handleKeyDown = (e) =>{if (e.keyCode === 13 || e.keyCode === 32) {e.preventDefault();elementRef.current.click();}}

并在链接中调用它

 handleKeyDown(e)}>

有人知道我哪里出错了或者我应该尝试什么吗?

解决方案

无法告诉您如何在 React 中执行此操作,但这是一个简单的过程,因此我相信您不会遇到困难.解决问题的关键部分是导航后"标题,但是如果可以,请尝试实现所有内容,因为这将极大地改善屏幕阅读器的用户体验.

导航的 SPA 模式最佳实践

推荐用于在 SPA 中处理导航的方法实际上非常简单,只需两个步骤.

  1. 告诉用户导航即将发生(在导航之前)
  2. 让用户知道加载已完成(导航后).

导航前(点击链接)

如果您使用 SPA 模式(因此会中断正常导航),您需要向用户发出正在加载页面的信号.例如我点击了你的链接,你需要让我知道一个动作正在执行(加载......),因为你用 e.preventDefault() 或等效物拦截了正常的浏览器行为.

最简单的方法是使用 aria-live=assertive 在解释页面正在加载的区域上.你可以谷歌如何正确实现,但基本上你会更新隐藏 div 的内容(

loading

) 和一些加载消息,第二个链接被点击.

这应该在进行任何 AJAX 调用之前完成.

导航后(加载新内容)

当新页面加载时,您需要管理焦点.

最好的方法是为每个具有 tabindex=-1" 的页面添加一个 1 级标题(

).使用 tabindex=-1" 这意味着标题不会被 JavaScript 以外的任何东西聚焦,因此不会干扰正常的文档流.

一旦页面加载完毕并且内容已完全填充,您在 JavaScript 导航功能中执行的最后一个操作就是将焦点放在此标题上.

这有两个好处:

  1. 它让用户知道他们现在在哪里
  2. 它还让他们知道页面加载何时完成(因为 AJAX 导航不会在大多数屏幕阅读器中通知页面何时加载).

此时您可能还想清除 <div aria-live="assertive"> 内容,以便为进一步导航做好准备.

When the user navigates to a new page by clicking the Link component the screen reader reads the new page perfectly and in correct order. If the user selects the new page by pressing enter or space the browser still navigates to the correct page but the screen reader does not read the page content.

The code to new page navigation looks like this:

  <Card className={classes.root}>
     <Link to={`/event/${eventId}`} component={CardActionArea}>
        <CardMedia
          className={classes.media}
        />
        <CardContent className={classes.cardContent}>
              ...some info..
        </CardContent>
     </Link>
  </Card>

I tried to solve this by creating a keyDownEvent as follows but it was no use:

 const elementRef = React.createRef<HTMLAnchorElement>();

  const handleKeyDown = (e) => {
    if (e.keyCode === 13 || e.keyCode === 32) {
      e.preventDefault();
      elementRef.current.click();
    }
  }

and called it in the Link

  <Link to={`/event/${eventId}`} component={CardActionArea} onKeyDown={(e) => handleKeyDown(e)}>

Anyone have an idea as to where I am going wrong or what I should give a try?

解决方案

Not able to tell you how to do this in React but it is a straightforward process so I am sure you won't struggle. The key part to fix your issue is the "after navigation" heading, however try to implement everything if you can as it will vastly improve screen reader user experience.

SPA pattern best practices for navigation

The method recommended for handling navigation in SPAs is actually quite straight forward with two steps.

  1. tell a user that navigation is about to occur (before navigation)
  2. let a user know that loading is complete (after navigation).

before navigation (link click)

You need to signal to a user that a page is loading if you are using a SPA pattern (and therefore interrupting normal navigation). e.g. I click your link, you need to let me know that an action is being performed (loading.....) as you intercept the normal browser behaviour with e.preventDefault() or equivalent.

The simplest way is to use aria-live=assertive on a region that explains the page is loading. You can Google how to implement that correctly but essentially you would update the content of a hidden div (<div aria-live="assertive" class="visually-hidden">loading</div>) with some loading message the second a link is clicked.

This should be done before any AJAX calls are made.

after navigation (new content loaded)

When the new page loads you need to manage focus.

The best way to do this is to add a level 1 heading (<h1>) to each page that has tabindex="-1". By using tabindex="-1" it means that the heading won't be focusable by anything other than your JavaScript so won't interfere with the normal document flow.

Once the page loads and the content has been populated fully the last action you perform in your JavaScript navigation function is to place the focus onto this heading.

This has two benefits:

  1. it lets the user know where they are now
  2. it also lets them know when the page load is complete (as AJAX navigation doesn't announce when the page is loaded in most screen readers).

At this point you may also want to clear the <div aria-live="assertive"> contents so that it is ready for further navigation.

这篇关于在 React.js 上使用键盘导航时,屏幕阅读器无法读取页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆