Start · Sprachen · JavaScript · Referenz · ElementInternals.ariaPosInSet

ElementInternals.ariaPosInSet

Eigenschaft

Liest oder setzt die Standard-ARIA-Position (<code>aria-posinset</code>) eines Custom Elements in seiner Liste oder seinem Baum, ohne dafür ein sichtbares Attribut anzulegen.

seit JavaScript Baseline 2023: Chrome 81+, Edge 81+, Safari 16.4+, Kategorie: webapi

Signatur

ElementInternals.ariaPosInSet

Beschreibung

Die Eigenschaft ariaPosInSet des ElementInternals-Interfaces entspricht dem ARIA-Attribut aria-posinset. Sie gibt an, an welcher Stelle (ab 1 gezählt) ein Element in seinem Satz von Listen- oder Baumelementen steht. Der Wert ist ein String mit einer Ganzzahl, z. B. "3", oder null, wenn keine Position gesetzt ist.

Anders als element.ariaPosInSet bzw. das HTML-Attribut aria-posinset legt der Wert über ElementInternals die Standard-Semantik eines autonomen Custom Elements fest. Er taucht nicht im DOM auf, und Nutzer der Komponente können ihn jederzeit mit einem eigenen aria-posinset-Attribut am Host-Element überschreiben.

Gebraucht wird das vor allem, wenn nicht alle Einträge einer Liste gleichzeitig im DOM liegen, etwa bei virtualisierten Listen, Paginierung oder nachgeladenen Baumknoten. Dann kann der Browser die Position nicht selbst aus der DOM-Struktur ablesen. Üblicherweise setzt man ariaPosInSet zusammen mit ariaSetSize und einer passenden Rolle wie option, listitem, treeitem, tab, menuitem oder row (in einem Treegrid).

Parameter

Name Typ Default Beschreibung
$value string | null null Beim Setzen: eine positive Ganzzahl als String (ab "1"), die kleiner oder gleich ariaSetSize ist. Mit null wird der Standardwert entfernt.

Rückgabewert

Typ
string | null
Beschreibung
Die aktuell gesetzte Standard-Position als String, z. B. "2", oder null, wenn keine gesetzt ist.

Beispiele

Listeneintrag als Custom Element mit fester Position

class MyOption extends HTMLElement {
  constructor() {
    super();
    // ElementInternals holen (nur einmal pro Element möglich)
    this._internals = this.attachInternals();
    this._internals.role = 'option';
  }

  connectedCallback() {
    const pos = this.dataset.pos ?? '1';
    this._internals.ariaPosInSet = pos;
    console.log('Position:', this._internals.ariaPosInSet);
  }
}

customElements.define('my-option', MyOption);

const opt = document.createElement('my-option');
opt.dataset.pos = '3';
document.body.append(opt);
Position: 3

Virtualisierte Liste: Position und Gesamtzahl setzen

class VirtualItem extends HTMLElement {
  #internals = this.attachInternals();

  constructor() {
    super();
    this.#internals.role = 'listitem';
  }

  // Wird vom Listen-Container beim Scrollen aufgerufen
  update(index, total, text) {
    this.textContent = text;
    this.#internals.ariaPosInSet = String(index + 1); // 1-basiert!
    this.#internals.ariaSetSize = String(total);
  }
}

customElements.define('virtual-item', VirtualItem);

const list = document.createElement('div');
list.setAttribute('role', 'list');
document.body.append(list);

// Nur 3 von 10.000 Einträgen liegen im DOM
const total = 10_000;
for (const i of [500, 501, 502]) {
  const item = document.createElement('virtual-item');
  item.update(i, total, `Eintrag ${i + 1}`);
  list.append(item);
}
// Screenreader sagt z. B.: "Eintrag 501, 501 von 10000"

Standardwert entfernen und Überschreiben durch das Attribut

class TreeNode extends HTMLElement {
  constructor() {
    super();
    this.internals = this.attachInternals();
    this.internals.role = 'treeitem';
    this.internals.ariaPosInSet = '2';
  }
}
customElements.define('tree-node', TreeNode);

const node = document.createElement('tree-node');
document.body.append(node);

// Das Attribut hat Vorrang vor dem internen Standardwert
node.setAttribute('aria-posinset', '5');
console.log(node.getAttribute('aria-posinset')); // "5"
console.log(node.internals.ariaPosInSet);        // "2" (unverändert)

// Standardwert komplett entfernen
node.internals.ariaPosInSet = null;
console.log(node.internals.ariaPosInSet);
5 2 null

// Wichtig · Fallstricke

  • Zählung ab 1: aria-posinset beginnt bei 1, Array-Indizes bei 0. Deshalb index + 1 übergeben.
  • String, keine Zahl: Der gelesene Wert ist immer ein String oder null. Zum Rechnen erst mit Number() umwandeln.
  • Keine Wirkung ohne passende Rolle: Die Eigenschaft wird nur bei Rollen wie option, listitem, treeitem, tab, menuitem, radio oder article ausgewertet. Setze die Rolle über internals.role.
  • Immer mit ariaSetSize kombinieren: Ohne Gesamtzahl kann der Screenreader nicht „x von y“ ansagen. Ist die Gesamtzahl unbekannt, setze ariaSetSize = \"-1\".
  • Kein DOM-Attribut: Der Wert erscheint nicht als Attribut im DOM, deshalb lässt er sich nicht mit CSS-Attributselektoren abfragen. Ein aria-posinset-Attribut am Host-Element hat Vorrang.
  • attachInternals() funktioniert nur bei autonomen Custom Elements und nur einmal pro Element. Bei einem zweiten Aufruf wirft der Browser eine NotSupportedError-DOMException.
  • Browser-Unterstützung: Firefox unterstützt die ARIA-Eigenschaften an ElementInternals erst ab Version 119. Für ältere Browser kannst du prüfen: 'ariaPosInSet' in ElementInternals.prototype. Fehlt die Eigenschaft, setzt du als Ersatz das Attribut am Host.