Start · Sprachen · JavaScript · Referenz · HTMLCollection

HTMLCollection

Schnittstelle

Array-ähnliche, meist <strong>live</strong> aktualisierte Sammlung von DOM-Elementen in Dokumentreihenfolge, mit Zugriff über Index oder <code>id</code>/<code>name</code>.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

interface HTMLCollection

Beschreibung

HTMLCollection ist eine geordnete Sammlung von Element-Objekten in Dokumentreihenfolge. Sie ist array-ähnlich: Sie hat eine Eigenschaft length und ihre Einträge lassen sich über numerische Indizes lesen. Sie ist aber kein echtes Array. Methoden wie map(), filter() oder forEach() gibt es nicht.

Solche Sammlungen liefern unter anderem document.getElementsByTagName(), document.getElementsByClassName(), element.children, document.forms, document.images, document.links und form.elements. Bei form.elements ist es die Unterschnittstelle HTMLFormControlsCollection.

Wichtigstes Merkmal: Eine HTMLCollection ist live. Sie spiegelt Änderungen am DOM sofort wider. Wird ein passendes Element eingefügt oder entfernt, ändern sich length und die Indizes ohne erneute Abfrage. Das spart neue Abfragen, führt aber bei Schleifen, die das DOM ändern, leicht zu Fehlern.

Wichtige Mitglieder:

  • length: Anzahl der Elemente (nur lesbar)
  • item(index): Element an Position index oder null
  • namedItem(name): erstes Element, dessen id oder (bei bestimmten Elementen) name passt, sonst null

Die Sammlung ist iterierbar, funktioniert also mit for...of, dem Spread-Operator und Array.from().

Parameter

Name Typ Default Beschreibung
$index Pflicht number Parameter von item(index): nullbasierte Position. Bei ungültigem Index ist das Ergebnis null. Die Kurzform collection[index] liefert dagegen undefined.
$name Pflicht string Parameter von namedItem(name): gesuchte id oder gesuchtes name-Attribut. Kurzform: collection[name] bzw. collection.name.

Rückgabewert

Typ
HTMLCollection
Beschreibung
Eine Instanz entsteht nur über DOM-Eigenschaften oder -Methoden wie element.children. Einen öffentlichen Konstruktor gibt es nicht. item() und namedItem() liefern Element | null.

Beispiele

Sammlung abrufen und Elemente lesen

// HTML: <ul id="menu"><li id="start">Start</li><li>Blog</li><li>Kontakt</li></ul>
const items = document.getElementById('menu').children;

console.log(items.length);                   // Anzahl
console.log(items[0].textContent);           // Index-Zugriff
console.log(items.item(1).textContent);      // item()
console.log(items.namedItem('start').textContent); // über id
console.log(items.item(99));                 // ungültiger Index
3 Start Blog Start null

Live-Verhalten im Vergleich zu querySelectorAll

const live = document.getElementsByClassName('todo');
const statisch = document.querySelectorAll('.todo');
console.log(live.length, statisch.length);

const neu = document.createElement('div');
neu.className = 'todo';
document.body.append(neu);

// Die HTMLCollection hat sich selbst aktualisiert, die NodeList nicht
console.log(live.length, statisch.length);
2 2 3 2

In ein Array umwandeln und Array-Methoden nutzen

const bilder = document.images; // HTMLCollection aller <img>

// Array.from erzeugt eine statische Kopie
const ohneAlt = Array.from(bilder).filter((img) => !img.alt);
console.log(`${ohneAlt.length} Bilder ohne Alternativtext`);

// Direkt iterieren mit for...of
for (const img of bilder) {
  img.loading = 'lazy';
}
2 Bilder ohne Alternativtext

Fallstrick: Elemente beim Iterieren entfernen

const hinweise = document.getElementsByClassName('hinweis');

// FALSCH: Durch das Live-Verhalten wird jedes zweite Element übersprungen
// for (let i = 0; i < hinweise.length; i++) hinweise[i].remove();

// RICHTIG A: rückwärts laufen
for (let i = hinweise.length - 1; i >= 0; i--) {
  hinweise[i].remove();
}

// RICHTIG B: vorher eine statische Kopie anlegen
// [...hinweise].forEach((el) => el.remove());
console.log(hinweise.length);

// Wichtig · Fallstricke

  • Live-Sammlung: Wer in einer Schleife Elemente entfernt, verschiebt oder Klassen ändert, die die Sammlung betreffen, verändert length und die Indizes während der Iteration. Deshalb rückwärts iterieren oder vorher mit Array.from() bzw. [...coll] kopieren.
  • Kein Array: Es gibt kein forEach(), map() usw. Anders als NodeList aus querySelectorAll() hat HTMLCollection auch kein forEach(). Array.isArray(coll) ergibt false.
  • Nur Elemente: Text- und Kommentarknoten sind nicht enthalten, im Gegensatz zu childNodes (eine NodeList).
  • Benannter Zugriff: coll.foo kann mit eingebauten Eigenschaften kollidieren, zum Beispiel bei einem Element mit id=\"length\". Eindeutiger ist namedItem(). Bei doppelten IDs wird nur das erste Element geliefert.
  • Performance: length wird bei manchen Änderungen neu berechnet. In großen DOMs mit häufigen Änderungen length vor der Schleife zwischenspeichern oder eine statische Kopie verwenden.
  • Kompatibilität: Wird von allen Browsern unterstützt. Iterierbarkeit mit for...of und Spread gibt es in allen modernen Browsern, im Internet Explorer nicht.