Signatur
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 PositionindexodernullnamedItem(name): erstes Element, dessenidoder (bei bestimmten Elementen)namepasst, sonstnull
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
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
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);
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';
}
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
lengthund die Indizes während der Iteration. Deshalb rückwärts iterieren oder vorher mitArray.from()bzw.[...coll]kopieren. - Kein Array: Es gibt kein
forEach(),map()usw. Anders alsNodeListausquerySelectorAll()hatHTMLCollectionauch keinforEach().Array.isArray(coll)ergibtfalse. - Nur Elemente: Text- und Kommentarknoten sind nicht enthalten, im Gegensatz zu
childNodes(eineNodeList). - Benannter Zugriff:
coll.fookann mit eingebauten Eigenschaften kollidieren, zum Beispiel bei einem Element mitid=\"length\". Eindeutiger istnamedItem(). Bei doppelten IDs wird nur das erste Element geliefert. - Performance:
lengthwird bei manchen Änderungen neu berechnet. In großen DOMs mit häufigen Änderungenlengthvor der Schleife zwischenspeichern oder eine statische Kopie verwenden. - Kompatibilität: Wird von allen Browsern unterstützt. Iterierbarkeit mit
for...ofund Spread gibt es in allen modernen Browsern, im Internet Explorer nicht.