NVDA屏幕阅读器无法读取jQuery日期选择器网格单元格值的问题
jQuery日期选择器NVDA无障碍修复方案
问题分析
你遇到的核心问题是:键盘导航日期选择器网格时,NVDA仅播报“空白”,但鼠标悬停正常。之前尝试用beforeShowDay添加aria-label的方法错误,因为该回调的第三个返回值仅用于设置单元格的title属性,无法直接注入自定义ARIA属性,导致属性被错误嵌入title中。
正确解决方案
通过在日期选择器渲染完成后(包括切换月份时)遍历DOM,为日期单元格内的<a>标签(键盘导航的焦点元素)补充无障碍属性,具体代码如下:
$(document).ready(function () { $('#ui-datepicker-div').addClass("month-calendar-widget"); $(".month-calendar input").datepicker({ showOtherMonths: true, minDate: 0, beforeShow: function () { $('#ui-datepicker-div').addClass("month-calendar-widget"); // 延迟执行确保DOM完全渲染 setTimeout(() => { updateDatepickerAria(); }, 0); }, onChangeMonthYear: function(year, month, inst) { // 切换月份后重新更新无障碍属性 setTimeout(() => { updateDatepickerAria(); }, 0); } }).datepicker("setDate", convertDateToUTC(new Date())); // 统一处理无障碍属性的工具函数 function updateDatepickerAria() { $('#ui-datepicker-div .ui-datepicker-calendar td').each(function() { const $td = $(this); const $dateLink = $td.find('a'); if (!$dateLink.length) return; // 从单元格数据属性和链接文本中获取日期信息 const month = $td.data('month'); const year = $td.data('year'); const day = $dateLink.text().trim(); const targetDate = new Date(year, month, day); // 格式化NVDA播报的日期字符串 const dateLabel = $.datepicker.formatDate('MM d, yy', targetDate); // 为焦点元素添加无障碍属性 $dateLink.attr({ 'aria-label': dateLabel, 'role': 'gridcell' }); // 根据单元格选中状态更新aria-selected $dateLink.attr('aria-selected', $td.hasClass('ui-datepicker-current-day') ? 'true' : 'false'); }); } });
关键说明
- 焦点元素定位:键盘导航时,焦点实际落在日期单元格内的
<a>标签上,而非<td>本身,因此需要为<a>添加ARIA属性。 - DOM时机处理:使用
setTimeout确保在日期选择器DOM渲染完成后再修改属性,避免操作未生成的元素。 - 月份切换适配:通过
onChangeMonthYear事件在切换月份时重新执行属性更新,确保新渲染的日期单元格也具备无障碍支持。
内容的提问来源于stack exchange,提问作者havij
相关产品推荐
相关产品推荐

