Signatur
Beschreibung
Element ist die zentrale Schnittstelle für alle Elemente im DOM-Baum. Sie erbt von Node und damit indirekt von EventTarget. Spezialisierte Schnittstellen bauen darauf auf: HTMLElement für HTML-Elemente, SVGElement für SVG und MathMLElement für MathML. Alles, was in allen Dokumenttypen gleich funktioniert, steht in Element.
Zu den wichtigsten Eigenschaften gehören id, className, classList, attributes, tagName, innerHTML, outerHTML, children, firstElementChild, scrollTop und clientWidth. Die häufigsten Methoden sind querySelector(), querySelectorAll(), closest(), matches(), getAttribute()/setAttribute(), toggleAttribute(), append(), prepend(), before(), after(), replaceWith(), remove(), getBoundingClientRect(), scrollIntoView(), attachShadow() und animate().
Man erzeugt Element nie direkt mit new Element(), denn der Konstruktor wirft einen TypeError. Elemente bekommt man stattdessen über document.createElement(), document.createElementNS(), über Abfragen wie querySelector() oder über eigene Klassen, die von HTMLElement erben (Custom Elements). Mit el instanceof Element prüft man, ob ein Knoten ein Element ist und nicht etwa ein Text- oder Kommentarknoten.
In der Praxis nutzt man Element zum Durchlaufen und Ändern des DOM, zum Setzen von Attributen und CSS-Klassen, für Event-Delegation mit closest(), zum Messen von Layout und Scroll-Position und für Web Components mit Shadow DOM.
Rückgabewert
document.createElement() (liefert HTMLElement, eine Unterklasse von Element) oder von querySelector() (liefert Element | null).Beispiele
Element erzeugen, konfigurieren und einfügen
// Elemente entstehen über document.createElement, nicht über new Element()
const karte = document.createElement('article');
karte.id = 'karte-1';
karte.classList.add('karte', 'hervorgehoben');
karte.setAttribute('data-produkt-id', '42');
const titel = document.createElement('h2');
titel.textContent = 'Kaffeemühle';
karte.append(titel, 'Preis: 49 €');
document.body.append(karte);
console.log(karte instanceof Element); // true
console.log(karte.tagName); // "ARTICLE"
console.log(karte.dataset.produktId); // "42"
console.log(karte.outerHTML);
Event-Delegation mit closest() und matches()
// Ein Listener auf der Liste statt einer auf jedem Button
const liste = document.querySelector('#aufgaben');
liste.addEventListener('click', (event) => {
// event.target kann ein Textknoten-Elternteil wie <span> sein
const button = event.target.closest('button[data-aktion]');
if (!button || !liste.contains(button)) return;
const eintrag = button.closest('li');
if (button.matches('[data-aktion="loeschen"]')) {
eintrag.remove();
} else if (button.matches('[data-aktion="erledigt"]')) {
eintrag.classList.toggle('erledigt');
eintrag.toggleAttribute('aria-checked');
}
});
Layout messen und in den sichtbaren Bereich scrollen
const fehlerfeld = document.querySelector('.feld--fehler');
if (fehlerfeld) {
const rect = fehlerfeld.getBoundingClientRect();
const sichtbar = rect.top >= 0 && rect.bottom <= window.innerHeight;
console.log(`Position oben: ${Math.round(rect.top)}px, sichtbar: ${sichtbar}`);
if (!sichtbar) {
fehlerfeld.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
fehlerfeld.querySelector('input')?.focus({ preventScroll: true });
}
Shadow DOM an ein Element anhängen
const host = document.createElement('div');
document.body.append(host);
const shadow = host.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>p { color: rebeccapurple; }</style>
<p>Gekapselter Inhalt</p>
`;
console.log(host.shadowRoot === shadow); // true
console.log(document.querySelector('p') === null); // true, wenn sonst kein <p> existiert
// Wichtig · Fallstricke
- Kein Konstruktor:
new Element()wirft einenTypeError: Illegal constructor. Nutzedocument.createElement()oder Custom Elements, die vonHTMLElementerben. - Element oder Node:
childNodes,firstChildundnextSiblingliefern auch Text- und Kommentarknoten. Wer nur Elemente will, nimmtchildren,firstElementChildundnextElementSibling. - XSS-Gefahr: Eigenschaften und Methoden wie
innerHTML,outerHTMLundinsertAdjacentHTML()werten ihren Inhalt als HTML aus. Nutzereingaben darf man dort nie ungeprüft einsetzen. Für reinen Text isttextContentdie richtige Wahl. Wo HTML nötig ist, sollte man es bereinigen (z. B. mit DOMPurify) oder Trusted Types über die CSP erzwingen. - Attribut oder Eigenschaft:
getAttribute('value')liefert den Wert aus dem HTML-Markup,input.valuedagegen den aktuellen Zustand. Die beiden laufen nicht immer gleich. - Performance: Wer Layout-Werte wie
getBoundingClientRect(),offsetWidthoderscrollTopausliest, nachdem er das DOM geändert hat, zwingt den Browser zu einem synchronen Reflow („Layout Thrashing“). Besser ist es, zuerst alle Werte zu lesen und danach gesammelt zu schreiben. - Kompatibilität: Die Grundfunktionen gehen in allen Browsern. Neuere Methoden wie
append(),replaceChildren(),toggleAttribute(),checkVisibility()undsetHTMLUnsafe()gibt es erst in aktuellen Browsern. Der Internet Explorer kennt einige davon nicht.