Signatur
Beschreibung
Mit querySelectorAll() durchsuchen Sie alle Nachfahren-Elemente eines DocumentFragment nach einem oder mehreren CSS-Selektoren. Die Treffer kommen in Dokumentreihenfolge zurück, also per Tiefensuche in Vorordnung (Elternelement vor seinen Kindern, Geschwister von links nach rechts).
Gebraucht wird das vor allem, wenn Sie DOM-Strukturen außerhalb des sichtbaren Dokuments vorbereiten: beim Befüllen von <template>-Inhalten (template.content), bei Fragmenten aus Range.createContextualFragment() oder beim Zusammenbauen vieler Knoten vor einem einzigen Einfügen. Weil das Fragment nicht im Dokument hängt, lösen Änderungen daran kein Reflow aus.
Wichtig: Die zurückgegebene NodeList ist statisch und wird nicht aktualisiert, wenn sich das Fragment später ändert. Außerdem gibt es in einem Fragment keinen Wurzel-Elementknoten. Selektoren wie :root treffen deshalb nichts, und :scope steht für das Fragment selbst.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $selectors Pflicht | string | Ein gültiger CSS-Selektor oder eine kommagetrennte Liste von Selektoren, z. B. "li.aktiv, a[href^='http']". |
Rückgabewert
NodeList mit allen passenden Element-Knoten. Ist sie leer, gab es keinen Treffer (es kommt nie null zurück).Beispiele
Template-Inhalt befüllen, bevor er ins DOM kommt
// HTML: <template id="karte"><div class="karte"><h2 class="titel"></h2><p class="text"></p></div></template>
const template = document.querySelector('#karte');
const fragment = template.content.cloneNode(true);
const felder = fragment.querySelectorAll('.titel, .text');
felder[0].textContent = 'Willkommen';
felder[1].textContent = 'Schön, dass Sie da sind.';
console.log(felder.length);
document.body.append(fragment);
Fragment programmatisch aufbauen und durchsuchen
const fragment = new DocumentFragment();
const produkte = [
{ name: 'Apfel', vorrat: 12 },
{ name: 'Birne', vorrat: 0 },
{ name: 'Kiwi', vorrat: 3 }
];
for (const { name, vorrat } of produkte) {
const li = document.createElement('li');
li.textContent = name;
if (vorrat === 0) li.classList.add('ausverkauft');
fragment.append(li);
}
// Alle ausverkauften Einträge markieren
fragment.querySelectorAll('li.ausverkauft').forEach((li) => {
li.setAttribute('aria-disabled', 'true');
li.textContent += ' (ausverkauft)';
});
console.log([...fragment.querySelectorAll('li')].map((li) => li.textContent));
document.querySelector('ul').append(fragment);
HTML-String parsen und externe Links absichern
const html = '<p><a href="https://example.com">Extern</a> <a href="/intern">Intern</a></p>';
const fragment = document.createRange().createContextualFragment(html);
const externe = fragment.querySelectorAll('a[href^="http"]');
externe.forEach((a) => {
a.target = '_blank';
a.rel = 'noopener noreferrer';
});
console.log(externe.length);
// Wichtig · Fallstricke
- Statische Liste: Anders als z. B.
childrenwird dieNodeListnicht automatisch aktualisiert. Fragen Sie nach Änderungen erneut ab. - Fragment ist nach dem Einfügen leer: Nach
append(fragment)sind die Knoten ins Dokument verschoben. Ein weiterer Aufruf vonfragment.querySelectorAll()liefert dann eine leere Liste. Bereits vorhandene Referenzen zeigen aber weiter auf die jetzt eingefügten Elemente. - Ungültige Selektoren lösen eine
SyntaxError-DOMExceptionaus. Setzen Sie Benutzereingaben nur maskiert mitCSS.escape()in Selektoren ein. - Kein Array:
NodeListkenntforEach(), aber nichtmap()oderfilter(). Wandeln Sie sie dafür mit[...liste]oderArray.from()um. - Template-Inhalte:
template.contentist selbst einDocumentFragment. Klonen Sie es vor dem Befüllen, sonst verändern Sie die Vorlage. - Sicherheit: Mit
createContextualFragment()geparstes HTML kann beim Einfügen Skripte ausführen. Fremde Eingaben vorher bereinigen, z. B. mit DOMPurify oder der Sanitizer-API. - Wird von allen modernen Browsern unterstützt.
NodeList.prototype.forEachfehlt nur in sehr alten Browsern (z. B. IE).