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

为动态加载内容配置屏幕阅读器的问题排查

屏幕阅读器无障碍问题排查与修复

问题概述

表单中输入邮政编码后,下拉城市建议、加载状态(ProgressIcon)、选中地址展示(ShowSelection)均无法被屏幕阅读器自动播报,仅错误提示(CityError)正常工作,已尝试aria-live但未生效。

逐个组件修复方案

1. ProgressIcon 组件

  • 问题核心:aria-live需要作用在始终存在于DOM中的容器上,若组件通过display: none隐藏,屏幕阅读器会忽略其监听;直接给容器加aria-label的可靠性低于显性文本。
  • 修复代码:
    <div 
      style={{ visibility: showFetchProgress ? 'visible' : 'hidden', opacity: showFetchProgress ? 1 : 0 }}
      aria-live="assertive"
      role="status"
    >
      <LoadingIcon size={'small'} aria-hidden="true" />
      <span className="sr-only">正在获取城市和州信息</span>
    </div>
    
    • 用visibility替代display: none,保证DOM节点始终存在,让aria-live能捕获状态变化
    • 新增仅屏幕阅读器可见的文本(.sr-only是通用的"仅阅读器可见"样式类),替代aria-label,提升兼容性
    • 给加载图标加aria-hidden="true",避免阅读器识别无意义的图标元素

2. DropdownOptions(城市建议下拉)

  • 问题核心:下拉菜单未与邮编输入框建立关联,且缺少标准的无障碍语义,aria-live未监听菜单内容的更新通知。
  • 修复步骤与代码:
    1. 先给邮编输入框补充关联属性:
      <input 
        type="text" 
        id="zipcode-input"
        aria-controls="city-suggestions"
        aria-expanded={showSuggestions}
        aria-describedby="suggestions-count"
      />
      
    2. 改造下拉菜单容器与选项:
      <CitySuggestionWrapper
        id="city-suggestions"
        isOpen={showSuggestions}
        style={{ display: showSuggestions ? 'block' : 'none' }}
      >
        <div id="suggestions-count" aria-live="polite" className="sr-only">
          {cityStates?.length > 0 ? `${cityStates.length}个城市建议` : ''}
        </div>
        <DropdownOptionsWrapper
          aria-expanded={showSuggestions}
          error={error}
          role="listbox"
        >
          {cityStates?.map((item: any) => (
            <DropdownOptions
              key={item.city}
              id={item.city}
              role="option"
              aria-selected={selectedCity?.city === item.city}
              onMouseDown={() => selectItem(item, dispatch)}
            >
              <button
                tabIndex={-1} // 由listbox容器统一管理焦点
                onKeyDown={(event) => keyPressSelectItem(event, item)}
              >
                {displayCityAddress(item)}
              </button>
            </DropdownOptions>
          ))}
        </DropdownOptionsWrapper>
      </CitySuggestionWrapper>
      
    • 用aria-controls关联输入框与下拉菜单,让阅读器明确两者的控制关系
    • 新增suggestions-count的live区域,主动播报建议数量,让用户感知下拉内容
    • 给菜单加role="listbox"、选项加role="option"和aria-selected,符合WAI-ARIA下拉菜单的标准语义

3. ShowSelection 组件

  • 问题核心:组件通过display: none隐藏时,aria-live无法监听内容更新;缺少明确的状态提示文本。
  • 修复代码:
    <div 
      aria-live="polite"
      style={{ visibility: showAddress ? 'visible' : 'hidden', height: showAddress ? 'auto' : 0, overflow: 'hidden' }}
    >
      {showAddress ? `已选择地址:${displayCityAddress(selectedCity)}` : ''}
    </div>
    
    • 用visibility+高度控制显示,保证DOM节点始终存在
    • 补充明确的状态前缀文本,让阅读器清晰播报选中结果

通用无障碍规则

  • aria-live容器必须始终存在于DOM中,不能用display: none切换显示,否则会被阅读器忽略
  • assertive仅用于紧急信息(如错误提示),普通更新用polite,避免干扰用户操作
  • 优先使用语义化标签:用<button>替代<a role="button">,用标准WAI-ARIA角色实现组件语义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:25:22