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

JAWS无法读取aria-describedby关联错误文本的问题排查

问题:JAWS屏幕阅读器无法在表单字段获焦时播报错误提示文本

我正在为Web应用添加无障碍功能,表单内有两个必填字段,分别绑定独立的span错误提示元素。已经用aria-invalid标记无效字段,通过aria-describedby关联错误提示元素,但JAWS在输入字段获得焦点时,不会朗读对应的错误提示文本。相关代码如下:

<form id="kiosksform" action="loc/save" method="post">
  <h1 class="title mt-2" id="registration-title">Create Kiosk</h1>
  <div class="bg-3 text-left">
    <table id="table" class="text-left table table-hover ml-0 table_edit mt-5">
      <thead>
        <tr>
          <th class="text-center" scope="col"><u data-toggle="tooltip" title="Item"></u></th>
          <th class="text-center" scope="col"><u data-toggle="tooltip" title="Enter the value">Value</u></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td class="kiosk-table-data">KIOSK Code</td>
          <td class="kiosk_table_data">
            <input type="text" name="kiosk_code" id="kiosk_code_id" value="" data-toggle="tooltip"
                   title="Enter kiosk code" class="pt1 p1-2" required 
                   aria-describedby="kiosk_code_validation" aria-invalid="false" 
                   onkeyup="validateFields()">
          </td>
        </tr>
        <tr>
          <td class="kiosk-table-data">KIOSK Name</td>
          <td class="kiosk_table_data">
            <input type="text" name="kiosk_name" id="kiosk_name_id" value="" data-toggle="tooltip"
                   title="Enter kiosk name" class="pt1 p1-2" required 
                   aria-describedby="kiosk_name_validation" aria-invalid="false" 
                   onkeyup="validateFields()">
          </td>
        </tr>
      </tbody>
    </table>

    <div class="button-holder mt-3">
      <button type="submit" onclick="return validateForm()" id="regButton" 
              class="btn btn-primary btn-width" data-toggle="tooltip" 
              title="Click to save your changes">Save</button>
      <a href="/loc" id="regButtonCancel" class="btn btn-width text-decoration-none"
         data-toggle="tooltip" title="Click to cancel transaction">Cancel</a>
    </div>

    <div class="container mt-3">
      <span id="kiosk_code_validation" class="text-danger text-center m1"> </span>
      <span id="kiosk_name_validation" class="text-danger text-center m1"> </span>
    </div>
  </div>
</form>

<script>
  function validateFields() {
    let formValidated      = false
    let kioskCodeValidated = false
    let kioskNameValidated = false

    let kioskCode = document.getElementById('kiosk_code_id');
    let kioskName = document.getElementById('kiosk_name_id');
    let kioskCodeValidation = document.getElementById('kiosk_code_validation');
    let kioskNameValidation = document.getElementById('kiosk_name_validation');

    document.getElementById("regButton").disabled = true

    if (kioskCode.value.length < 2) {
      kioskCodeValidation.innerHTML = "Kiosk Code must be at least two characters in length"
      kioskCodeValidation.style.display="block"
      kioskCode.setAttribute("aria-invalid", "true")
    } else {
      kioskCodeValidated = true
      kioskCodeValidation.style.display="none"
      kioskCodeValidation.innerHtml = ""
      kioskCode.setAttribute("aria-invalid", "false")
    }

    if (kioskName.value.length < 2) {
      kioskNameValidation.innerHTML = "Please enter a full Kiosk Name or location"
      kioskNameValidation.style.display="block"
      kioskName.setAttribute("aria-invalid", "true")
    } else {
      kioskNameValidated = true
      kioskNameValidation.style.display="none"
      kioskNameValidation.innerHtml = ""
      kioskName.setAttribute("aria-invalid", "false")
    }

    if (kioskCodeValidated && kioskNameValidated) {
        formValidated = true
        document.getElementById("regButton").disabled = false;
    }
  }

  validateFields();
</script>

请问我遗漏了哪些配置,才能让JAWS在字段获得焦点时播报错误文本?


解决方案

你遇到的问题是几个无障碍细节处理不到位,以下是具体修复点:

1. 为错误提示元素添加实时区域属性aria-live

JAWS需要通过aria-live区域检测内容变化并自动播报。给错误提示的span添加aria-live="polite",这样错误文本更新时,屏幕阅读器会在当前任务完成后播报内容,同时字段获焦时也能关联读取提示。

修改后的错误提示元素:

<span id="kiosk_code_validation" class="text-danger text-center m1" aria-live="polite"></span>
<span id="kiosk_name_validation" class="text-danger text-center m1" aria-live="polite"></span>

2. 修正错误提示的隐藏方式

用style.display="none"会让屏幕阅读器完全忽略该元素,即使aria-describedby关联了也无法读取。建议改用aria-hidden="true"配合视觉隐藏样式(比如visibility: hidden; height: 0; overflow: hidden;),同时在字段有效时清空提示文本。

3. 动态管理aria-describedby关联

当字段验证通过时,应该移除aria-describedby属性,避免JAWS尝试读取空的错误提示元素;当字段无效时再重新添加关联。

4. 修复代码拼写错误

代码里的innerHtml应为innerHTML(H需大写),这个错误会导致无法正确清空错误提示文本,残留内容可能干扰无障碍播报。

完整修改后的核心代码片段

HTML部分(错误提示元素)

<span id="kiosk_code_validation" class="text-danger text-center m1" aria-live="polite" aria-hidden="true"></span>
<span id="kiosk_name_validation" class="text-danger text-center m1" aria-live="polite" aria-hidden="true"></span>

JavaScript部分(validateFields函数)

function validateFields() {
  let formValidated      = false
  let kioskCodeValidated = false
  let kioskNameValidated = false

  let kioskCode = document.getElementById('kiosk_code_id');
  let kioskName = document.getElementById('kiosk_name_id');
  let kioskCodeValidation = document.getElementById('kiosk_code_validation');
  let kioskNameValidation = document.getElementById('kiosk_name_validation');

  document.getElementById("regButton").disabled = true

  if (kioskCode.value.length < 2) {
    kioskCodeValidation.innerHTML = "Kiosk Code must be at least two characters in length"
    kioskCodeValidation.style.visibility = "visible";
    kioskCodeValidation.style.height = "auto";
    kioskCodeValidation.setAttribute("aria-hidden", "false");
    kioskCode.setAttribute("aria-invalid", "true");
    kioskCode.setAttribute("aria-describedby", "kiosk_code_validation");
  } else {
    kioskCodeValidated = true
    kioskCodeValidation.innerHTML = "";
    kioskCodeValidation.style.visibility = "hidden";
    kioskCodeValidation.style.height = "0";
    kioskCodeValidation.setAttribute("aria-hidden", "true");
    kioskCode.setAttribute("aria-invalid", "false");
    kioskCode.removeAttribute("aria-describedby");
  }

  if (kioskName.value.length < 2) {
    kioskNameValidation.innerHTML = "Please enter a full Kiosk Name or location"
    kioskNameValidation.style.visibility = "visible";
    kioskNameValidation.style.height = "auto";
    kioskNameValidation.setAttribute("aria-hidden", "false");
    kioskName.setAttribute("aria-invalid", "true");
    kioskName.setAttribute("aria-describedby", "kiosk_name_validation");
  } else {
    kioskNameValidated = true
    kioskNameValidation.innerHTML = "";
    kioskNameValidation.style.visibility = "hidden";
    kioskNameValidation.style.height = "0";
    kioskNameValidation.setAttribute("aria-hidden", "true");
    kioskName.setAttribute("aria-invalid", "false");
    kioskName.removeAttribute("aria-describedby");
  }

  if (kioskCodeValidated && kioskNameValidated) {
      formValidated = true
      document.getElementById("regButton").disabled = false;
  }
}

完成以上修改后,JAWS在字段获焦时会正确播报错误提示文本,同时内容更新时也会实时通知用户。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 17:52:06