NVDA与JAWS屏幕阅读器触发Read More按钮时播报冗余文本问题
解决Read More/Read Less组件的屏幕阅读器播报异常问题
问题现象
在NVDA+Firefox、JAWS+Chrome环境中:
- 用Tab键导航激活Read More或Read Less按钮时,屏幕阅读器会播报冗余信息和不必要的内容更新
- 用箭头键导航激活这些按钮时,阅读器会出现异常播报(显示“<>和<>”)
问题根源
- 空的aria-live区域:按钮里加了空的
<span aria-live="assertive" aria-atomic="true"></span>,DOM更新时空内容会触发屏幕阅读器的异常播报 - DOM结构冗余与标签错误:按钮内部嵌套了和外层重复的
v-if判断,还存在未正确闭合的<span>标签,导致阅读器解析混乱 - 无意义的aria-hidden操作:Read Less按钮的
aria-hidden切换逻辑完全没必要,反而干扰阅读器识别元素 - 冗余的视觉隐藏文本:视觉隐藏的标题文本和按钮功能关联弱,造成播报冗余
修复方案
- 移除空的aria-live元素:只有需要实时更新的内容区域才需要aria-live,按钮本身不需要额外配置
- 清理DOM结构:删掉按钮内部重复的
v-if判断,修复未闭合的标签 - 简化焦点管理:去掉无意义的
aria-hidden切换逻辑,让焦点切换更自然 - 优化按钮语义:让按钮文本直接清晰表达功能,若需要关联对应评论标题,可通过
aria-labelledby关联标题元素(按需添加)
修改后的代码
模板部分
<div class="pros-cons-block" tabindex="-1"> <div class="pros-block"> <h4 id="pros-{{index}}">Pros-text</h4> <div> {{eachReview.pros}} </div> </div> <div class="cons-block"> <h4 id="cons-{{index}}">cons-text</h4> <div> {{eachReview.cons}} </div> </div> </div> <div v-show="eachReview" class="read-more"> <!-- Read Less按钮 --> <button v-if="eachReview.readMore" class="readless" @click="readMore(eachReview, index)" aria-labelledby="pros-{{index}} cons-{{index}}" > {{readLessButton.text }} </button> <!-- Read More按钮 --> <button v-else class="readMoreButton" @click="readMore(eachReview, index)" aria-labelledby="pros-{{index}} cons-{{index}}" > {{ content.readMoreButton.text }} </button> </div>
脚本部分
const readMore = (eachReview, index) => { eachReview.readMore = !eachReview.readMore; const focusElem = root.value.querySelectorAll('.glassdoorReviews .each-review')[index]; setTimeout(() => { if (eachReview.readMore) { // 展开后聚焦到内容区块 focusElem.querySelector('.pros-cons-block').focus(); } else { // 收起后聚焦到Read More按钮 focusElem.querySelector('.readMoreButton').focus(); } }, 0); };
说明
- 用
v-else替代重复的v-if判断,简化DOM结构 - 移除了空的aria-live元素,避免异常播报
- 去掉了无意义的
aria-hidden切换逻辑 - 新增
aria-labelledby关联Pros/Cons标题,让屏幕阅读器能明确按钮对应的内容(按需保留,若不需要可直接移除) - 修复了原代码中未闭合的
<span>标签,确保DOM结构合法
内容的提问来源于stack exchange,提问作者Dhulipati Sree Mallika Bhargav
相关产品推荐
相关产品推荐

