JavaScript Anfänger

Was ist das DOM? JavaScript und HTML verbinden

Was ist das DOM?

Das DOM (Document Object Model) ist die Brücke zwischen JavaScript und HTML. Es ermöglicht dir, Webseiten dynamisch zu verändern – Elemente hinzufügen, entfernen, Styles ändern und auf Benutzeraktionen reagieren.

Das DOM verstehen

Wenn der Browser eine HTML-Datei lädt, erstellt er daraus eine Baumstruktur – das DOM:

<!DOCTYPE html>
<html>
  <head>
    <title>Meine Seite</title>
  </head>
  <body>
    <h1>Hallo Welt</h1>
    <p>Ein Absatz</p>
  </body>
</html>

Wird zu diesem Baum:

document
└── html
    ├── head
    │   └── title
    │       └── "Meine Seite"
    └── body
        ├── h1
        │   └── "Hallo Welt"
        └── p
            └── "Ein Absatz"

Jedes HTML-Element wird zu einem Node (Knoten) im DOM. JavaScript kann jeden dieser Knoten lesen und verändern.

Das document-Objekt

document ist dein Einstiegspunkt ins DOM:

// Das gesamte HTML-Dokument
console.log(document);

// Der <html>-Tag
console.log(document.documentElement);

// Der <head>-Tag
console.log(document.head);

// Der <body>-Tag
console.log(document.body);

// Der Titel der Seite
console.log(document.title);
document.title = "Neuer Titel!";  // Ändert den Browser-Tab

Elemente finden

getElementById

Findet ein Element anhand seiner ID:

<h1 id="main-title">Willkommen!</h1>
const title = document.getElementById("main-title");
console.log(title);  // Das H1-Element
console.log(title.textContent);  // "Willkommen!"

querySelector (Empfohlen!)

Findet das erste Element, das zum CSS-Selektor passt:

// Nach ID
const title = document.querySelector("#main-title");

// Nach Klasse
const button = document.querySelector(".btn-primary");

// Nach Tag
const firstParagraph = document.querySelector("p");

// Komplexe Selektoren
const navLink = document.querySelector("nav a.active");
const input = document.querySelector('input[type="email"]');
const firstItem = document.querySelector("ul > li:first-child");

querySelectorAll

Findet alle Elemente, die zum Selektor passen:

// Alle Paragraphen
const paragraphs = document.querySelectorAll("p");
console.log(paragraphs.length);  // Anzahl

// Durch alle iterieren
paragraphs.forEach((p, index) => {
    console.log(`Paragraph ${index}: ${p.textContent}`);
});

// Alle Buttons mit Klasse
const buttons = document.querySelectorAll(".btn");

// In Array umwandeln (für Array-Methoden)
const buttonsArray = [...document.querySelectorAll(".btn")];

Element-Eigenschaften lesen

<a href="https://example.com" id="link" class="btn primary" data-id="123">
    Klick mich
</a>
const link = document.querySelector("#link");

// Text-Inhalt
console.log(link.textContent);  // "Klick mich"

// Attribute
console.log(link.href);         // "https://example.com"
console.log(link.id);           // "link"
console.log(link.className);    // "btn primary"

// Dataset (data-* Attribute)
console.log(link.dataset.id);   // "123"

// Klassen
console.log(link.classList);    // ["btn", "primary"]

Elemente verändern

Text ändern

const title = document.querySelector("h1");

// Text setzen (sicher!)
title.textContent = "Neuer Titel!";

Attribute ändern

const link = document.querySelector("a");

// Attribut setzen
link.href = "https://newsite.com";
link.setAttribute("target", "_blank");

// Attribut lesen
console.log(link.getAttribute("href"));

// Attribut entfernen
link.removeAttribute("target");

// Attribut prüfen
if (link.hasAttribute("href")) {
    console.log("Hat href!");
}

Klassen manipulieren

const element = document.querySelector(".box");

// Klasse hinzufügen
element.classList.add("active");
element.classList.add("highlight", "visible");  // Mehrere

// Klasse entfernen
element.classList.remove("active");

// Klasse togglen (an/aus)
element.classList.toggle("active");

// Prüfen ob Klasse existiert
if (element.classList.contains("active")) {
    console.log("Ist aktiv!");
}

// Klasse ersetzen
element.classList.replace("old-class", "new-class");

Styles ändern

const box = document.querySelector(".box");

// Einzelne Styles
box.style.backgroundColor = "blue";
box.style.color = "white";
box.style.padding = "20px";

// Achtung: CSS-Eigenschaften in camelCase!
// background-color → backgroundColor
// font-size → fontSize

// Besser: Klassen verwenden!
box.classList.add("highlighted");

Elemente erstellen

Neues Element erstellen

// Element erstellen
const newDiv = document.createElement("div");

// Inhalt setzen
newDiv.textContent = "Ich bin neu!";
newDiv.className = "card";
newDiv.id = "new-card";

// Attribute setzen
newDiv.setAttribute("data-id", "123");

// Zum DOM hinzufügen
document.body.appendChild(newDiv);

Komplexere Elemente

function createCard(title, description) {
    const card = document.createElement("div");
    card.className = "card";

    const cardTitle = document.createElement("h3");
    cardTitle.textContent = title;

    const cardDesc = document.createElement("p");
    cardDesc.textContent = description;

    const cardButton = document.createElement("button");
    cardButton.textContent = "Mehr erfahren";
    cardButton.className = "btn";

    // Zusammenbauen
    card.appendChild(cardTitle);
    card.appendChild(cardDesc);
    card.appendChild(cardButton);

    return card;
}

// Verwenden
const container = document.querySelector("#cards");
container.appendChild(createCard("Titel 1", "Beschreibung 1"));
container.appendChild(createCard("Titel 2", "Beschreibung 2"));

Elemente einfügen & entfernen

Einfügen

const container = document.querySelector("#container");
const newElement = document.createElement("div");

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

// Am Anfang einfügen
container.prepend(newElement);

// Vor einem Element
const reference = document.querySelector("#reference");
container.insertBefore(newElement, reference);

// Moderne Methoden
container.append(newElement);       // Am Ende
container.prepend(newElement);      // Am Anfang
reference.before(newElement);       // Vor Element
reference.after(newElement);        // Nach Element

Entfernen

const element = document.querySelector("#to-remove");

// Modern
element.remove();

// Klassisch (über Parent)
element.parentNode.removeChild(element);

// Alle Kinder entfernen
while (container.firstChild) {
    container.removeChild(container.firstChild);
}

DOM Navigation

Von einem Element zu anderen navigieren:

const item = document.querySelector(".item");

// Eltern
item.parentNode;        // Direkter Elternknoten
item.parentElement;     // Elternelement
item.closest(".container");  // Nächster Vorfahre mit Selektor

// Kinder
item.children;          // Alle Kind-Elemente
item.firstElementChild; // Erstes Kind-Element
item.lastElementChild;  // Letztes Kind-Element

// Geschwister
item.nextElementSibling;     // Nächstes Element
item.previousElementSibling; // Vorheriges Element

Praktisches Projekt: Todo-Liste UI

<div id="todo-app">
    <input type="text" id="todo-input" placeholder="Neue Aufgabe...">
    <button id="add-btn">Hinzufügen</button>
    <ul id="todo-list"></ul>
</div>
const input = document.querySelector("#todo-input");
const addBtn = document.querySelector("#add-btn");
const list = document.querySelector("#todo-list");

function createTodoItem(text) {
    const li = document.createElement("li");
    li.className = "todo-item";

    const span = document.createElement("span");
    span.textContent = text;

    const deleteBtn = document.createElement("button");
    deleteBtn.textContent = "Löschen";
    deleteBtn.className = "delete-btn";

    // Delete-Funktion
    deleteBtn.addEventListener("click", () => {
        li.remove();
    });

    // Abhaken durch Klick
    span.addEventListener("click", () => {
        li.classList.toggle("completed");
    });

    li.appendChild(span);
    li.appendChild(deleteBtn);

    return li;
}

function addTodo() {
    const text = input.value.trim();

    if (text === "") {
        input.focus();
        return;
    }

    const todoItem = createTodoItem(text);
    list.appendChild(todoItem);

    input.value = "";
    input.focus();
}

// Event Listeners
addBtn.addEventListener("click", addTodo);

input.addEventListener("keypress", (e) => {
    if (e.key === "Enter") {
        addTodo();
    }
});

Performance-Tipps

1. Selektoren cachen

// Schlecht - jedes Mal suchen
for (let i = 0; i < 100; i++) {
    document.querySelector("#container").appendChild(createItem());
}

// Gut - einmal suchen
const container = document.querySelector("#container");
for (let i = 0; i < 100; i++) {
    container.appendChild(createItem());
}

2. DocumentFragment für viele Elemente

const list = document.querySelector("#list");
const fragment = document.createDocumentFragment();

for (let i = 0; i < 100; i++) {
    const li = document.createElement("li");
    li.textContent = `Item ${i}`;
    fragment.appendChild(li);  // Kein Reflow
}

list.appendChild(fragment);  // Ein Reflow

3. Klassen statt Inline-Styles

// Schlecht - mehrere Reflows
element.style.width = "100px";
element.style.height = "100px";

// Gut - ein Reflow
element.classList.add("red-box");

Zusammenfassung

MethodeBeschreibung
querySelector()Ein Element finden
querySelectorAll()Alle Elemente finden
createElement()Element erstellen
appendChild()Element hinzufügen
remove()Element entfernen
classList.add/remove/toggle()Klassen ändern
textContentText lesen/setzen
setAttribute()Attribut setzen

Übung: Baue die Todo-Liste nach und erweitere sie um eine “Alle löschen”-Funktion!