You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React实现屏幕阅读器播报组件显示状态的技术问题

实现屏幕阅读器播报区块显示状态的解决方案

问题描述

需求为实现屏幕阅读器播报某区块的显示状态,该区块的显示由用户点击链接切换的布尔值控制。现有实现代码如下:

import { Row } from 'react-bootstrap';
...
const [shouldDisplay, setShouldDisplay] = useState<boolean>(false);
...
return(
 {!shouldDisplay && (
    <a href="somepage.com" onClick={setShouldDisplay(true)} />
  )}

  {shouldDisplay && (
    <Row>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p>
    </Row>)}
);

已尝试为Row添加aria-live="polite",但屏幕阅读器仍未播报该Lorem ipsum区块的显示状态,期望实现类似react-bootstrap的Collapse组件使用aria-expanded="true"时的播报效果(如播报“Lorem ipsum部分已显示”或“已展开”)。

解决方案

1. 修复触发按钮的无障碍属性与事件绑定

原触发链接存在两处问题:

  • onClick直接执行setShouldDisplay(true),组件渲染时会立即修改状态,需改为传递函数
  • 缺少无障碍属性,屏幕阅读器无法识别其为内容控制开关

修改后的触发链接:

<a 
  href="#" 
  onClick={(e) => {
    e.preventDefault(); // 阻止默认跳转,此按钮为内容开关而非跳转链接
    setShouldDisplay(true);
  }}
  aria-expanded={shouldDisplay}
  aria-controls="lorem-ipsum-section" // 关联目标区块的ID
>
  显示内容
</a>
  • aria-expanded用于告知屏幕阅读器当前内容的展开/收起状态
  • aria-controls建立按钮与目标区块的关联,提升无障碍体验

2. 为目标区块添加稳定容器与正确无障碍属性

避免直接通过条件渲染移除整个区块,改用hidden属性控制显示,同时保留容器以让aria-live监测内容变化:

<Row 
  id="lorem-ipsum-section"
  hidden={!shouldDisplay}
  aria-live="polite"
>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p>
</Row>
  • hidden属性控制显示状态,容器始终存在,确保aria-live能捕捉到内容变化
  • id需与触发按钮的aria-controls值一致,强化关联
  • aria-live="polite"会在屏幕阅读器空闲时播报内容变化

3. 自定义播报文本(可选)

若需要更明确的播报内容(如“Lorem ipsum部分已显示”),可添加一个视觉隐藏的aria-live区域,手动更新播报文本:

<div 
  aria-live="polite"
  style={{ position: 'absolute', left: '-10000px', top: 'auto', width: '1px', height: '1px', overflow: 'hidden' }}
>
  {shouldDisplay && 'Lorem ipsum部分已显示'}
</div>

该区域视觉不可见,但屏幕阅读器会读取其中的文本,适合自定义播报话术。

完整修改代码

import { Row } from 'react-bootstrap';
import { useState } from 'react';

function ExampleComponent() {
  const [shouldDisplay, setShouldDisplay] = useState<boolean>(false);

  return(
    <>
      <a 
        href="#" 
        onClick={(e) => {
          e.preventDefault();
          setShouldDisplay(true);
        }}
        aria-expanded={shouldDisplay}
        aria-controls="lorem-ipsum-section"
      >
        显示Lorem ipsum内容
      </a>

      <Row 
        id="lorem-ipsum-section"
        hidden={!shouldDisplay}
        aria-live="polite"
      >
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. </p>
      </Row>

      {/* 可选:自定义播报文本 */}
      <div 
        aria-live="polite"
        style={{ position: 'absolute', left: '-10000px', top: 'auto', width: '1px', height: '1px', overflow: 'hidden' }}
      >
        {shouldDisplay && 'Lorem ipsum部分已显示'}
      </div>
    </>
  );
}

内容的提问来源于stack exchange,提问作者Lav C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 04:17:03