Document Object Model (DOM)

Geschätzte Lektüre: 13 Minuten 553 Ansichten

Das Document Object Model (DOM) ist eine der grundlegendsten und wichtigsten Schnittstellen in der Webentwicklung. Es stellt eine programmierbare Repräsentation einer Webseite dar und ermöglicht es Entwicklern, mit JavaScript auf die Struktur, den Inhalt und das Styling einer Seite zuzugreifen und diese dynamisch zu verändern. Das DOM ist im Grunde eine baumartige Struktur, die alle Elemente einer HTML-Seite als Objekte organisiert, die manipuliert werden können.

Die Grundstruktur des DOM

Das DOM organisiert ein HTML-Dokument als Hierarchie von Knoten (Nodes), die einen Baum (den sogenannten DOM-Baum) bilden. Jedes Element, jeder Attribut und jeder Textabschnitt im HTML wird zu einem Knoten in diesem Baum. Es gibt verschiedene Arten von Knoten:
• Document Node: Die Wurzel des Baumes, repräsentiert das gesamte Dokument
• Element Nodes: Repräsentieren HTML-Elemente (wie <div>, <p>, <h1>)
• Attribute Nodes: Repräsentieren Attribute von HTML-Elementen (wie class, id)
• Text Nodes: Enthalten den tatsächlichen Text innerhalb von Elementen

Beispiel eines einfachen HTML-Dokuments und seines DOM-Baums:

<!DOCTYPE html>
<html>
<head>
    <title>Meine Seite</title>
</head>
<body>
    <h1>Willkommen</h1>
    <p>Ein Absatz mit <em>betontem</em> Text.</p>
</body>
</html>

Der entsprechende DOM-Baum würde so aussehen:

Document
└── html
    ├── head
    │   └── title
    │       └── "Meine Seite"
    └── body
        ├── h1
        │   └── "Willkommen"
        └── p
            ├── "Ein Absatz mit "
            ├── em
            │   └── "betontem"
            └── " Text."

Zugriff auf DOM-Elemente

JavaScript bietet mehrere Methoden, um auf Elemente im DOM zuzugreifen:

1. getElementById()

Diese Methode gibt das Element mit der angegebenen ID zurück. IDs sollten innerhalb eines Dokuments eindeutig sein.

// HTML: <div id="header">...</div>
const header = document.getElementById('header');

2. getElementsByClassName()

Gibt eine HTMLCollection aller Elemente mit der angegebenen Klasse zurück.

// HTML: <p class="important">...</p> <div class="important">...</div>
const importantElements = document.getElementsByClassName('important');

3. getElementsByTagName()

Gibt eine HTMLCollection aller Elemente mit dem angegebenen Tag-Namen zurück.

// Gibt alle <p>-Elemente zurück
const paragraphs = document.getElementsByTagName('p');

4. querySelector() und querySelectorAll()

Diese modernen Methoden erlauben CSS-Selektoren als Parameter:

// Gibt das erste Element mit der Klasse 'menu-item' zurück
const menuItem = document.querySelector('.menu-item');

// Gibt alle Elemente mit der Klasse 'menu-item' zurück
const allMenuItems = document.querySelectorAll('.menu-item');

Manipulation des DOM

Nachdem wir auf Elemente zugreifen können, wollen wir sie verändern.

Inhalte ändern:

const heading = document.querySelector('h1');
// textContent für reinen Text
heading.textContent = 'Neue Überschrift';

// innerHTML für HTML-Inhalt
const div = document.getElementById('content');
div.innerHTML = '<p>Neuer HTML-Inhalt</p>';

Attribute manipulieren:

const image = document.querySelector('img');
// Attribut setzen
image.setAttribute('src', 'neues-bild.jpg');

// Attribut lesen
const src = image.getAttribute('src');

// Direkter Zugriff über Eigenschaften
image.alt = 'Beschreibung des Bildes';

Klassen manipulieren:

const element = document.getElementById('meinElement');
// Klasse hinzufügen
element.classList.add('aktiv');

// Klasse entfernen
element.classList.remove('inaktiv');

// Klasse umschalten
element.classList.toggle('sichtbar');

Erstellen und Einfügen von Elementen

Neue Elemente erstellen:

// Neues div-Element erstellen
const newDiv = document.createElement('div');

// Inhalt hinzufügen
newDiv.textContent = 'Ich bin ein neues Div';

// Attribute setzen
newDiv.className = 'box';
newDiv.id = 'box-1';

Elemente einfügen:

const container = document.getElementById('container');

// Am Ende einfügen
container.appendChild(newDiv);

// Vor einem bestimmten Element einfügen
const referenceElement = document.getElementById('referenz');
container.insertBefore(newDiv, referenceElement);

// Komplexeres Einfügen mit insertAdjacentHTML
container.insertAdjacentHTML('beforeend', '<p>Neuer Absatz</p>');

Ereignisbehandlung (Event Handling)

Das DOM ermöglicht es, auf Benutzerinteraktionen zu reagieren.

Ereignis-Listener hinzufügen:

const button = document.getElementById('meinButton');

// Methode 1: Direkte Zuweisung
button.onclick = function() {
    console.log('Button wurde geklickt!');
};

// Methode 2: addEventListener (besser, da mehrere Handler möglich)
button.addEventListener('click', function(event) {
    console.log('Button wurde geklickt!', event);
});

Häufige Ereignisse:
• click – Mausklick
• mouseover/mouseout – Maus bewegt sich über/nicht mehr über Element
• keydown/keyup – Tastendruck
• submit – Formular wird abgeschickt
• load – Element (meist Fenster) ist fertig geladen
• change – Eingabefeld wurde verändert

DOM Traversierung

Man kann sich im DOM-Baum bewegen, um verwandte Elemente zu finden.

const element = document.querySelector('p');

// Elternknoten
const parent = element.parentNode;

// Kindknoten
const firstChild = element.firstChild;
const children = element.childNodes; // NodeList aller Kinder

// Geschwisterknoten
const nextSibling = element.nextSibling;
const previousSibling = element.previousSibling;

Performance-Optimierung beim DOM-Zugriff

DOM-Operationen sind relativ langsam, daher sollte man sie optimieren:

01. DOM-Zugriffe minimieren: Ergebnisse zwischen speichern

// Schlecht: Mehrfacher Zugriff
for (let i = 0; i < 100; i++) {
    document.getElementById('element').style.left = i + 'px';
}

// Gut: Einmaliger Zugriff
const element = document.getElementById('element');
for (let i = 0; i < 100; i++) {
    element.style.left = i + 'px';
}

02. Batch-Operationen: Mehrere Änderungen auf einmal durchführen

// DocumentFragment für Batch-Operationen
const fragment = document.createDocumentFragment();

for (let i = 0; i < 100; i++) {
    const newElement = document.createElement('div');
    newElement.textContent = 'Element ' + i;
    fragment.appendChild(newElement);
}

document.body.appendChild(fragment);

03. Layout-Thrashing vermeiden: Lesen und Schreiben abwechseln verursacht teure Neuberechnungen

Das Virtual DOM

Moderne Frameworks wie React verwenden ein Virtual DOM – eine abstrakte Repräsentation des echten DOM. Dies ermöglicht:
01. Effiziente Updates durch Vergleich des virtuellen mit dem echten DOM
02. Minimierung der teuren direkten DOM-Manipulationen
03. Bessere Performance für komplexe Anwendungen

Praxisbeispiel: Eine dynamische To-Do-Liste

<!DOCTYPE html>
<html>
<head>
    <title>To-Do Liste</title>
    <style>
        .completed { text-decoration: line-through; color: #999; }
    </style>
</head>
<body>
    <h1>Meine To-Dos</h1>
    <input type="text" id="newTodo" placeholder="Neues To-Do">
    <button id="addBtn">Hinzufügen</button>
    <ul id="todoList"></ul>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const todoInput = document.getElementById('newTodo');
            const addButton = document.getElementById('addBtn');
            const todoList = document.getElementById('todoList');
            
            // To-Do hinzufügen
            addButton.addEventListener('click', function() {
                const todoText = todoInput.value.trim();
                if (todoText) {
                    addTodoItem(todoText);
                    todoInput.value = '';
                }
            });
            
            // Auch mit Enter hinzufügen
            todoInput.addEventListener('keypress', function(e) {
                if (e.key === 'Enter') {
                    addButton.click();
                }
            });
            
            function addTodoItem(text) {
                const li = document.createElement('li');
                
                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.addEventListener('change', function() {
                    li.classList.toggle('completed', checkbox.checked);
                });
                
                const textSpan = document.createElement('span');
                textSpan.textContent = text;
                
                const deleteBtn = document.createElement('button');
                deleteBtn.textContent = '×';
                deleteBtn.addEventListener('click', function() {
                    li.remove();
                });
                
                li.appendChild(checkbox);
                li.appendChild(textSpan);
                li.appendChild(deleteBtn);
                
                todoList.appendChild(li);
            }
        });
    </script>
</body>
</html>

Fortgeschrittene DOM-Techniken

Event Delegation

Statt jedem Element einen Event-Listener hinzuzufügen, nutzt man die Tatsache, dass Events „bubbeln“ (nach oben propagieren):

document.getElementById('todoList').addEventListener('click', function(e) {
    if (e.target.tagName === 'BUTTON') {
        e.target.parentElement.remove();
    }
});

MutationObserver

Beobachtet Änderungen im DOM:

const observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        console.log('DOM wurde verändert!', mutation);
    });
});

observer.observe(document.getElementById('container'), {
    childList: true,
    subtree: true,
    attributes: true
});

Zusammenfassung

Das Document Object Model (DOM) ist die Schnittstelle zwischen HTML und JavaScript, die es ermöglicht, Webseiten dynamisch zu gestalten. Durch das DOM können wir:
01. Auf jedes Element einer Webseite zugreifen
02. Inhalt, Struktur und Stil verändern
03. Auf Benutzerinteraktionen reagieren
04. Komplexe, interaktive Anwendungen erstellen

Das Verständnis des DOM ist essentiell für jeden JavaScript-Entwickler, da es die Grundlage für die Interaktion mit Webseiten bildet. Moderne Frameworks abstrahieren zwar oft direkte DOM-Manipulationen, aber ein tiefes Verständnis des DOM-Konzepts bleibt unverzichtbar für die Entwicklung performanter und robuster Webanwendungen.

Dieses Dokument teilen

Document Object Model (DOM)

Oder Link kopieren

INHALT

Abonnieren

×
Cancel