Ein wenig JavaScript
Diese Schulung handelt von HTML und CSS. An einigen Stellen fehlt aber ein kleiner Anstoß: Ein Knopf soll ein Menü öffnen. Dafür genügt ein Muster, das du auch ohne JavaScript-Kenntnisse verwenden kannst.
Was du am Ende kannst
Abschnitt betitelt „Was du am Ende kannst“- ein Skript richtig einbinden
- ein Element finden und auf einen Klick reagieren
- eine Klasse umschalten, das Aussehen bleibt im CSS
- den Zustand auch für Screenreader mitteilen
Live-Coding zum Mitmachen
⤓ demo-21-javascript.zip herunterladenDer Ordner starter ist der Ausgangsstand, fertig der Stand nach dem Live-Coding.
Enthält: app.js, index.html, stil.css
Das Muster
Abschnitt betitelt „Das Muster“.inhalt { display: none; padding: 0.5rem; background: #e0e7ff; }.inhalt.offen { display: block; }<button id="knopf" type="button" aria-expanded="false" aria-controls="bereich">Mehr anzeigen</button><div class="inhalt" id="bereich">Jetzt bin ich sichtbar.</div><script> const knopf = document.querySelector("#knopf"); const bereich = document.querySelector("#bereich");
knopf.addEventListener("click", () => { const offen = bereich.classList.toggle("offen"); knopf.setAttribute("aria-expanded", offen); });</script>Es besteht aus vier Teilen:
- Finden:
document.querySelectornimmt denselben Selektor wie dein CSS. - Reagieren:
addEventListener("click", …)führt eine Funktion aus, sobald jemand klickt. - Umschalten:
classList.togglesetzt die Klasse oder nimmt sie weg und gibt zurück, ob sie jetzt gesetzt ist. - Mitteilen:
aria-expandedsagt dem Screenreader, ob der Bereich offen ist.
Das Aussehen steht weiterhin im CSS. Das Skript ändert nur einen Zustand. Dadurch bleibt beides getrennt, und die Gestaltung kannst du anpassen, ohne das Skript anzufassen.
Das Skript einbinden
Abschnitt betitelt „Das Skript einbinden“<head> <script src="app.js" defer></script></head>defer führt das Skript erst aus, wenn das HTML fertig gelesen ist. Ohne defer findet querySelector die Elemente womöglich noch
nicht. Fehler im Skript zeigt die Konsole in den DevTools: anders als CSS meldet JavaScript seine Fehler.
Zuerst ohne JavaScript denken
Abschnitt betitelt „Zuerst ohne JavaScript denken“Bevor du zu JavaScript greifst, prüfe, ob es ohne geht:
| Aufgabe | Ohne JavaScript |
|---|---|
| Auf- und zuklappen | details |
| Dialog schließen | form method="dialog", Escape-Taste |
| Eingaben prüfen | required, type, pattern |
| Auf Zustände reagieren | :has(), :checked |
| Hover, Fokus | CSS |
Für das Öffnen eines Dialogs und ein umschaltbares Menü brauchen wir dagegen ein Skript.
Live-Coding: Das mobile Menü
Abschnitt betitelt „Live-Coding: Das mobile Menü“Auf dem Handy nimmt das Menü zu viel Platz weg. Es soll hinter einem Knopf verschwinden und auf breiten Bildschirmen immer sichtbar
sein. Der Dialog bekommt bei der Gelegenheit sein onclick aus dem HTML entfernt.
// Mobiles Menü: Das Skript ändert nur einen Zustand. Das Aussehen bleibt im CSS.const menueKnopf = document.querySelector(".menue-knopf");const menue = document.querySelector("#hauptmenue");
menueKnopf.addEventListener("click", () => { const offen = menue.classList.toggle("offen"); menueKnopf.setAttribute("aria-expanded", offen);});
// Der Dialog braucht kein onclick mehr im HTMLconst dialog = document.querySelector("#neue-aufgabe");
document.querySelector(".filter .knopf").addEventListener("click", () => { dialog.showModal();});/* Ohne die Klasse „offen“ ist das Menü auf dem Handy zu */@media (max-width: 47.99rem) { .seitenleiste:not(.offen) { display: none; }}Die Media Query mit max-width sorgt dafür, dass die Klasse auf breiten Bildschirmen keine Rolle spielt.
Starter für die Übung
⤓ uebung-21-javascript.zip herunterladenZIP-Datei entpacken und den Ordner in VS Code öffnen (Datei → Ordner öffnen).
Enthält: app.js, index.html, stil.css, uebung.js
Schreibe deinen Code in uebung.js. Die Variablen menue, menueKnopf und dialog aus app.js kannst du weiterverwenden.
Stufe 1: Escape
Abschnitt betitelt „Stufe 1: Escape“Ein offenes Menü schließt sich mit der Escape-Taste, und der Fokus kehrt auf den Knopf zurück. Tipp: keydown-Ereignis am document,
ereignis.key === "Escape", und menueKnopf.focus().
Stufe 2: Filter
Abschnitt betitelt „Stufe 2: Filter“Die Auswahl „Stufe“ blendet Karten aus. Reagiere auf change, gehe mit for…of über alle .karte und setze karte.hidden.
Stufe 3: Neue Karte
Abschnitt betitelt „Stufe 3: Neue Karte“Beim Schließen des Dialogs entsteht eine neue Karte in der ersten Spalte. Tipp: document.createElement, textContent und append.
Warum textContent und nie innerHTML für Eingaben von Nutzern?
Für Schnelle
Abschnitt betitelt „Für Schnelle“Zeige im Titel jeder Spalte die Anzahl sichtbarer Karten an: JavaScript setzt ein data-anzahl-Attribut, und das CSS zeigt es mit
attr() an. Oder baue einen Schalter für den Dunkelmodus, der sich die Wahl in localStorage merkt.