如何使nvda读取一些正在执行的状态消息?

问题描述

问题是我想让NVDA在按下按钮后读取一些消息。例如,有一个按钮“添加新行”,它将新行添加到网格中。使用NVDA屏幕阅读器的用户按按钮上的Enter,然后我要通知他有关成功结果的信息(已添加行)。另一个示例是我有一个表单,用户可以在其中进行一些更改。表单上提供了“保存”按钮-装完后我想通知用户“更改已保存”。有什么方法可以在不引发烤面包机消息的情况下做到这一点? 我想补充一下,在按下按钮后,焦点仍然停留在它们上。

解决方法

您正在寻找the aria-live attribute

这允许您通过更改容器上带有aria-live的文本来向屏幕阅读器用户提供更新。

对于您要使用aria-live="polite"的用例,aria-live="assertive"仅应用于对时间敏感的信息,例如注销提示等。

一个不可见的aria-live区域

您不必具有可见的aria-live区域,但必须可由屏幕阅读器访问。

为此,我们可以使用my visually hidden class使其在视觉上隐藏起来(比sr-only更好,并且由于clip已过时而被证明)

.visually-hidden { 
    border: 0;
    padding: 0;
    margin: 0;
    position: absolute !important;
    height: 1px; 
    width: 1px;
    overflow: hidden;
    clip: rect(1px 1px 1px 1px); /* IE6,IE7 - a 0 height clip,off to the bottom right of the visible 1px box */
    clip: rect(1px,1px,1px); /*maybe deprecated but we need to support legacy browsers */
    clip-path: inset(50%); /*modern browsers,clip-path works inwards from each corner*/
    white-space: nowrap; /* added line to stop words getting smushed together (as they go onto seperate lines and some screen readers do not understand line feeds as a space */
}
<div class="visually-hidden" aria-live="polite">

Whatever you put in here via JavaScript will get read out to screen readers as an appropraite quiet time. This is not visible.

</div>

<p>This is visible</p>

来自MDN的示例

由于仅链接的答案是永远不好的,所以我在MDN的链接文章中提供了示例。

const PLANETS_INFO = {
  mercury: {
    title: 'Mercury',description: 'Mercury is the smallest and innermost planet in the Solar System. It is named after the Roman deity Mercury,the messenger to the gods.'
  },venus: {
    title: "Venus",description: 'Venus is the second planet from the Sun. It is named after the Roman goddess of love and beauty.'
  },earth: {
    title: "Earth",description: 'Earth is the third planet from the Sun and the only object in the Universe known to harbor life.'
  },mars: {
    title: "Mars",description: 'Mars is the fourth planet from the Sun and the second-smallest planet in the Solar System after Mercury. In English,Mars carries a name of the Roman god of war,and is often referred to as the "Red Planet".'
  }
};

function renderPlanetInfo(planet) {
  const planetTitle = document.querySelector('#planetTitle');
  const planetDescription = document.querySelector('#planetDescription');
  
  if (planet in PLANETS_INFO) {
    planetTitle.textContent = PLANETS_INFO[planet].title;
    planetDescription.textContent = PLANETS_INFO[planet].description;
  } else {
    planetTitle.textContent = 'No planet selected';
    planetDescription.textContent = 'Select a planet to view its description';
  }
}

const renderPlanetInfoButton = document.querySelector('#renderPlanetInfoButton');

renderPlanetInfoButton.addEventListener('click',event => {
  const planetsSelect = document.querySelector('#planetsSelect');
  const selectedPlanet = planetsSelect.options[planetsSelect.selectedIndex].value;

  renderPlanetInfo(selectedPlanet);
});
<fieldset>
  <legend>Planet information</legend>
  <label for="planetsSelect">Planet:</label>
  <select id="planetsSelect" aria-controls="planetInfo">
    <option value="">Select a planet&hellip;</option>
    <option value="mercury">Mercury</option>
    <option value="venus">Venus</option>
    <option value="earth">Earth</option>
    <option value="mars">Mars</option>
  </select>
  <button id="renderPlanetInfoButton">Go</button>
</fieldset>

<div role="region" id="planetInfo" aria-live="polite">
  <h2 id="planetTitle">No planet selected</h2>
  <p id="planetDescription">Select a planet to view its description</p>
</div>

<p><small>Information courtesy <a href="https://en.wikipedia.org/wiki/Solar_System#Inner_Solar_System">Wikipedia</a></small></p>

,

建议使用仅屏幕阅读器的文本,以获取视觉上显而易见的信息,但对于无视力用户则不可用。我建议您尝试使用clip + clip-path方法作为渐进增强功能,以支持旧版本和新版本的浏览器。

.screenreader-text {
  border: 0;
  /*Clipping defines what part of an element should be displayed*/
  /* Deprecated clip property for older browsers */
  clip: rect(1px,1px);
  /* clip-path for newer browsers. inset(50%) defines an inset rectangle that makes the content disappear */
  clip-path: inset(50%);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute !important;
  width: 1px;
  word-wrap: normal !important;
}