ARIA 即時區域

使用 JavaScript,可以動態更改頁面的部分內容,而無需重新載入整個頁面——例如,動態更新搜尋結果列表,或顯示不需要使用者互動的離散警報或通知。雖然這些更改通常對可以看到頁面的使用者來說是視覺上明顯的,但它們可能不會對使用輔助技術的使用者很明顯。ARIA 即時區域彌合了這一差距,並提供了一種以輔助技術可以宣佈的方式以程式設計方式公開動態內容更改的方法。

注意: 輔助技術通常只宣佈即時區域內容的動態更改。在您想要宣佈更改的元素上包含 aria-live 屬性或專門的即時區域 role(例如 role="status")在更改發生之前有效——無論是在原始標記中,還是使用 JavaScript 動態新增。從一個空的即時區域開始,然後——在單獨的步驟中——更改區域內的內容。雖然規範中沒有明確說明,但瀏覽器/輔助技術確實包含對 role="alert" 的特殊處理:在大多數情況下,即使區域(已經包含通知/訊息)存在於頁面的初始標記中,或動態注入到頁面中,role="alert" 區域內的內容也會被宣佈。但是,請注意,role="alert" 區域在宣佈時會——根據特定的瀏覽器/輔助技術組合——自動新增字首“Alert”。

即時區域

在不重新載入頁面的情況下更新的動態內容通常是區域或小部件。不具有互動性的簡單內容更改應標記為即時區域。即時區域使用 aria-live 屬性明確表示。

aria-live: aria-live=POLITENESS_SETTING 用於設定螢幕閱讀器處理即時區域更新的優先順序——可能的設定包括:offpoliteassertive。此屬性是迄今為止最重要的屬性。

通常,只使用 aria-live="polite"。任何接收對使用者來說重要的更新的區域,但更新速度不快到令人討厭,都應該接收此屬性。螢幕閱讀器將在使用者空閒時說出更改。

aria-live="assertive" 僅應用於絕對需要使用者立即注意的時間敏感/關鍵通知。通常,對斷言式即時區域的更改會中斷螢幕閱讀器當前正在進行的任何宣佈。因此,它可能非常煩人且具有破壞性,並且應該謹慎使用。

與直覺相反,aria-live="off" 並不表示不應宣佈更改。當元素具有 aria-live="off"(或具有此隱式值的 role,例如 role="marquee"role="timer")時,元素內容的更改僅應在焦點位於元素上或元素內時宣佈。

基本示例:下拉框更新有用的螢幕資訊

一個專門提供行星資訊的網站提供了一個下拉框。當從下拉框中選擇一個行星時,頁面上的一個區域將更新為包含所選行星的資訊。

html
<fieldset>
  <legend>Planet information</legend>
  <label for="planetsSelect">Planet:</label>
  <select id="planetsSelect" aria-controls="planetInfo">
    <option value="">Select a planet…</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 from
    <a href="https://en.wikipedia.org/wiki/Solar_System">Wikipedia</a>
  </small>
</p>
js
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);
});

當用戶選擇一個新的行星時,即時區域中的資訊將被宣佈。由於即時區域具有 aria-live="polite",因此螢幕閱讀器將在使用者暫停之前等待宣佈更新。因此,向下移動列表並選擇另一個行星不會宣佈即時區域中的更新。即時區域中的更新將僅在最終選擇的行星時宣佈。

以下是在 Mac 上 VoiceOver 透過字幕宣佈即時區域更新的螢幕截圖

A screenshot of VoiceOver on Mac announcing the update to a live region. Subtitles are shown in the picture.

具有隱式即時區域屬性的角色

具有以下 role="…" 值的元素預設情況下充當即時區域

角色 描述 相容性說明
log 聊天、錯誤、遊戲或其他型別的日誌 為了最大限度地提高相容性,在使用此角色時新增冗餘的 aria-live="polite"
status 狀態列或螢幕區域,提供某種型別的更新狀態。螢幕閱讀器使用者有一個特殊的命令來閱讀當前狀態。 為了最大限度地提高相容性,在使用此角色時新增冗餘的 aria-live="polite"
alert 在螢幕上閃爍的錯誤或警告訊息。警報對於客戶端驗證通知使用者特別重要。 警報示例。 為了最大限度地提高相容性,有些人建議在使用此角色時新增冗餘的 aria-live="assertive"。但是,新增 aria-liverole="alert" 會在 iOS 上的 VoiceOver 中導致雙重朗讀問題。
progressbar 小部件和即時區域的混合體。與 aria-valueminaria-valuenowaria-valuemax 結合使用。(待定:在此處新增更多資訊)。
marquee 滾動文字,例如股票行情播報。
計時器 任何型別的計時器或時鐘,例如倒計時器或秒錶讀數。

其他即時區域屬性

動態區域得到很好的支援。Paciello Group 於 2014 年釋出了 關於動態區域支援狀況的資訊。Paul J. Adam 特別研究了 aria-atomicaria-relevant 的支援情況

  1. aria-atomic: aria-atomic=BOOLEAN 用於設定螢幕閱讀器是否應始終將動態區域作為整體呈現,即使只有該區域的一部分發生變化。可能的設定是:falsetrue。預設設定為 false
  2. aria-relevant : aria-relevant=[LIST_OF_CHANGES] 用於設定哪些型別的更改與動態區域相關。可能的設定是以下一項或多項:additionsremovalstextall。預設設定為:additions text

基本示例:aria-atomic

作為 aria-atomic 的說明,假設一個網站有一個簡單的時鐘,顯示小時和分鐘。時鐘每分鐘更新一次,新的剩餘時間覆蓋當前內容。

html
<div id="clock" role="timer" aria-live="polite">
  <span id="clock-hours"></span>
  <span id="clock-mins"></span>
</div>
js
/* basic JavaScript to update the clock */
function updateClock() {
  const now = new Date();
  document.getElementById("clock-hours").textContent = now.getHours();
  document.getElementById("clock-mins").textContent =
    `0${now.getMinutes()}`.substr(-2);
}

/* first run */
updateClock();

/* update every minute */
setInterval(updateClock, 60000);

函式首次執行時,將宣佈新增的整個字串。在隨後的呼叫中,將僅宣佈與先前內容相比發生變化的內容部分。例如,當時鍾從“17:33”變為“17:34”時,輔助技術將僅宣佈“34”,這對使用者來說不太有用。

解決此問題的一種方法是首先清除動態區域的所有內容(在本例中,將 <span id="clock-hours"><span id="clock-mins">innerHTML 設定為空),然後注入新內容。但是,這有時可能不可靠,因為它依賴於這兩個更新的確切時間。

aria-atomic="true" 確保每次更新動態區域時,都會完整宣佈所有內容(例如,“17:34”)。

html
<div id="clock" role="timer" aria-live="polite" aria-atomic="true"></div>

aria-atomic 的另一個示例 - 由於使用者操作而進行的更新/通知。

html
<div id="date-input">
  <label for="year">Year:</label>
  <input type="text" id="year" value="1990" onblur="change(event)" />
</div>

<div id="date-output" aria-atomic="true" aria-live="polite">
  The set year is:
  <span id="year-output">1990</span>
</div>
js
function change(event) {
  const yearOut = document.getElementById("year-output");

  switch (event.target.id) {
    case "year":
      yearOut.textContent = event.target.value;
      break;
    default:
      return;
  }
}

如果沒有 aria-atomic="true",螢幕閱讀器只會宣佈年份的更改值。使用 aria-atomic="true",螢幕閱讀器會宣佈“已設定的年份為:更改的值”。

基本示例:aria-relevant

使用 aria-relevant,您可以指定應宣佈哪些型別的更改/更新到動態區域。

例如,考慮一個聊天網站,該網站希望顯示當前登入使用者的列表。我們不僅希望宣佈當前登入的使用者,還希望在使用者列表中刪除時觸發公告。我們可以透過指定 aria-relevant="additions removals" 來實現這一點。

html
<ul id="roster" aria-live="polite" aria-relevant="additions removals">
  <!-- use JavaScript to add and remove users here -->
</ul>

ARIA 動態屬性的細分

  • aria-live="polite" 表示螢幕閱讀器應等到使用者處於空閒狀態後才能向用戶顯示更新。這是最常用的值,因為用“assertive”中斷使用者可能會中斷他們的流程。
  • aria-atomic 未設定(預設情況下為 false),因此只有新增或刪除的使用者才會被說出,每次不會說出整個花名冊。
  • aria-relevant="additions removals" 確保新增或刪除到花名冊中的使用者都會被說出。

另請參閱