Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| de:modul:m291:learningunits:lu07:theorie:lu07a_debugging [2026/03/22 15:08] – gkoch | de:modul:m291:learningunits:lu07:theorie:lu07a_debugging [2026/03/22 22:03] (aktuell) – ä gkoch | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| ====== LU07: Debugging – Fehler finden und verstehen ====== | ====== LU07: Debugging – Fehler finden und verstehen ====== | ||
| - | Debugging | + | {{: |
| + | |||
| + | Debugging bedeutet, mit dem Browser oder dem Code-Editor zu **Spuren des Fehlers** nachzuforschen | ||
| <WRAP center round tip 80%> | <WRAP center round tip 80%> | ||
| Zeile 14: | Zeile 16: | ||
| Eine gute Debugging-Gewohnheit folgt immer dieser Reihenfolge: | Eine gute Debugging-Gewohnheit folgt immer dieser Reihenfolge: | ||
| - | |||
| <WRAP round box 80% center> | <WRAP round box 80% center> | ||
| - | ^ Schritt ^ Frage ^ | + | ^ Schritt ^ Was Sie tun ^ ^ Beispiel |
| - | | **1. Read** | Lesen Sie die Fehlermeldung genau. Was steht da wirklich? | | + | | 1. Read | Lesen Sie die Fehlermeldung genau. |
| - | | **2. Reproduce** | Können | + | | 2. Reproduce | Lösen |
| - | | **3. Reduce** | Welches ist der kleinste mögliche Code, der das Problem | + | | 3. Reduce | Grenzen Sie das Problem |
| - | | **4. Fix** | Ändern Sie **eine** Sache – dann testen Sie sofort. | | + | | 4. Fix | Ändern Sie eine einzige |
| </ | </ | ||
| Zeile 34: | Zeile 35: | ||
| ^ Schritt ^ Werkzeug ^ Hilft bei ^ | ^ Schritt ^ Werkzeug ^ Hilft bei ^ | ||
| | 1 | Formatter / Linter | Syntaxfehler (fehlende Klammern, Tippfehler, falsch geschachteltes HTML) | | | 1 | Formatter / Linter | Syntaxfehler (fehlende Klammern, Tippfehler, falsch geschachteltes HTML) | | ||
| - | | 2 | Console | + | | 2 | Console | Laufzeitfehler (was passiert, während der Code läuft) | |
| | 3 | Elements-Tab | Rendering-Fehler (was macht der Browser aus Ihrem CSS/HTML) | | | 3 | Elements-Tab | Rendering-Fehler (was macht der Browser aus Ihrem CSS/HTML) | | ||
| </ | </ | ||
| - | |||
| ===== Werkzeug 1: Formatter & Linter ===== | ===== Werkzeug 1: Formatter & Linter ===== | ||
| Zeile 47: | Zeile 47: | ||
| {{: | {{: | ||
| - | WebStorm prüft den Code automatisch im Hintergrund. Farbige Unterwellungen bedeuten: | + | WebStorm prüft den Code automatisch im Hintergrund |
| * **Rot** → Fehler (der Code wird nicht korrekt ausgeführt) | * **Rot** → Fehler (der Code wird nicht korrekt ausgeführt) | ||
| * **Gelb** → Warnung (sollte behoben werden) | * **Gelb** → Warnung (sollte behoben werden) | ||
| Zeile 54: | Zeile 54: | ||
| {{: | {{: | ||
| \\ | \\ | ||
| - | //Webstorm | + | //WebStorm |
| {{: | {{: | ||
| \\ | \\ | ||
| - | //Bei Fehlern in Webstorm, fahren | + | //Fahren |
| + | |||
| + | WebStorm erkennt unter anderem: | ||
| + | * Fehlende Dateiendungen: | ||
| + | * Falsche Anführungszeichen: | ||
| + | * Tippfehler in CSS-Eigenschaften: | ||
| === Formatieren === | === Formatieren === | ||
| Mit **Ctrl+Alt+L** (Windows) / **Cmd+Alt+L** (Mac) formatieren Sie die ganze Datei (alles wird schön ausgerichtet). | Mit **Ctrl+Alt+L** (Windows) / **Cmd+Alt+L** (Mac) formatieren Sie die ganze Datei (alles wird schön ausgerichtet). | ||
| - | ==== VS Code + Prettier ==== | + | ==== VS Code: Prettier |
| {{: | {{: | ||
| {{: | {{: | ||
| + | {{: | ||
| - | Prettier ist eine Extension, die den Code beim Speichern automatisch formatiert. | + | Für VS Code brauchen Sie zwei separate Extensions, um dasselbe Niveau wie WebStorm zu erreichen: |
| - | **Einmalige Einrichtung: | + | **Prettier** formatiert den Code automatisch beim Speichern (Einrückung, |
| - Extensions-Tab öffnen (Ctrl+Shift+X / Cmd+Shift+X) | - Extensions-Tab öffnen (Ctrl+Shift+X / Cmd+Shift+X) | ||
| - | - Suchen: **Prettier – Code formatter** | + | - Suchen: **Prettier – Code formatter**, installieren |
| - | - Installieren | + | |
| - Settings öffnen (Ctrl+, / Cmd+,), suchen nach '' | - Settings öffnen (Ctrl+, / Cmd+,), suchen nach '' | ||
| Ab jetzt: **Ctrl+S / Cmd+S** → Code wird automatisch aufgeräumt und eingerückt. | Ab jetzt: **Ctrl+S / Cmd+S** → Code wird automatisch aufgeräumt und eingerückt. | ||
| - | ==== Typische | + | **HTMLHint** prüft die HTML-Struktur und meldet typische |
| + | - Suchen: **HTMLHint**, installieren | ||
| + | - Keine weitere Konfiguration nötig – funktioniert sofort | ||
| + | - Website mit Dokumentation aller Regeln: [[https:// | ||
| - | Diese Fehler erzeugen | + | <WRAP center round info 80%> |
| + | **Hinweis:** Für CSS gibt es [[https:// | ||
| + | </ | ||
| - | **Falscher Dateiname (kein Fehler, | + | ==== Typische |
| - | <WRAP round box 80% center> | + | **Falsche Anführungszeichen** (WebStorm & HTMLHint): |
| - | <code html> | + | |
| - | <!-- ❌ Dateiendung fehlt (.css / .js) – Browser findet die Datei nicht --> | + | |
| - | <link href=" | + | |
| - | <script src=" | + | |
| - | + | ||
| - | <!-- ✅ Korrekt --> | + | |
| - | <link href=" | + | |
| - | <script src=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | **Falsche Anführungszeichen (aus Word oder Moodle kopiert):** | + | |
| <WRAP round box 80% center> | <WRAP round box 80% center> | ||
| <code html> | <code html> | ||
| - | <!-- ❌ Typografische Anführungszeichen – Browser | + | <!-- ❌ Typografische Anführungszeichen |
| - | <link href=„style.css” rel=„stylesheet”> | + | <link href=„style.css" |
| <!-- ✅ Gerade Anführungszeichen --> | <!-- ✅ Gerade Anführungszeichen --> | ||
| Zeile 108: | Zeile 106: | ||
| </ | </ | ||
| + | <WRAP center round important 80%> | ||
| + | **Vorsicht beim Kopieren aus Moodle oder Word:** Textverarbeitungsprogramme ersetzen gerade Anführungszeichen ('' | ||
| + | Fügen Sie kopierten Code immer als **Plain Text** ein: **Cmd+Shift+V** (Mac) / **Ctrl+Shift+V** (Windows). | ||
| + | </ | ||
| - | **Tippfehler in CSS-Eigenschaften:** | + | **Tippfehler in CSS-Eigenschaften** |
| <WRAP round box 80% center> | <WRAP round box 80% center> | ||
| <code css> | <code css> | ||
| - | /* ❌ ' | + | /* ❌ ' |
| .panel.open { | .panel.open { | ||
| heihgt: auto; | heihgt: auto; | ||
| Zeile 125: | Zeile 127: | ||
| } | } | ||
| </ | </ | ||
| + | |||
| + | {{: | ||
| + | // | ||
| </ | </ | ||
| - | Dieser Fehler ist besonders tückisch: das Accordion-Panel öffnet sich visuell nicht, obwohl das JavaScript korrekt funktioniert. Die Console zeigt keinen Fehler. Nur der Editor markiert '' | + | Dieser Fehler ist besonders tückisch: das Accordion-Panel öffnet sich visuell nicht, obwohl das JavaScript korrekt funktioniert. Die Console zeigt keinen Fehler. |
| Zeile 180: | Zeile 185: | ||
| <WRAP round box 80% center> | <WRAP round box 80% center> | ||
| <code js> | <code js> | ||
| - | // ❌ Fehler: ' | + | // ❌ Fehler: ' |
| buttons.forEach((button) => { | buttons.forEach((button) => { | ||
| button.addEventListener(' | button.addEventListener(' | ||
| Zeile 189: | Zeile 194: | ||
| </ | </ | ||
| - | {{: | + | {{: |
| **Was passiert:** | **Was passiert:** | ||
| Zeile 214: | Zeile 219: | ||
| </ | </ | ||
| - | ==== Häufige JS-Bugs aus dem Accordion-Projekt | + | ==== Script-Position: Ein stiller, häufiger Fehler |
| - | **Bug: | + | Wird die Verlinkung zum JavaScript-File im ''< |
| + | |||
| <WRAP round box 80% center> | <WRAP round box 80% center> | ||
| - | <code js> | + | === Script im <head> - falsch! |
| - | // ❌ Wählt nur den ersten Button – forEach funktioniert, | + | {{: |
| - | const buttons | + | |
| - | // ✅ Wählt alle Buttons | ||
| - | const buttons = document.querySelectorAll(' | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | **Bug: Fehlender Punkt vor dem Klassennamen** | ||
| - | |||
| - | <WRAP round box 80% center> | ||
| - | <code js> | ||
| - | // ❌ Sucht nach einem HTML-Tag < | ||
| - | const buttons = document.querySelectorAll(' | ||
| - | |||
| - | // ✅ Punkt vor Klassennamen nicht vergessen | ||
| - | const buttons = document.querySelectorAll(' | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | Dieser Fehler erzeugt **keinen roten Fehler** in der Console. Prüfen Sie mit: | ||
| - | <WRAP round box 80% center> | ||
| - | <code js> | ||
| - | console.log(' | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | **Bug: Variablenname-Konflikt in forEach** | ||
| - | |||
| - | <WRAP round box 80% center> | ||
| - | <code js> | ||
| - | // ❌ Aussen heisst die Variable ' | ||
| - | // → der äussere ' | ||
| - | button.forEach((button) => { | ||
| - | button.addEventListener(' | ||
| - | // ... | ||
| - | if (!panelIsOpen) { | ||
| - | panelElement.classList.add(' | ||
| - | button.setAttribute(' | ||
| - | } | ||
| - | }); | ||
| - | }); | ||
| - | |||
| - | // ✅ Klare, unterschiedliche Namen | ||
| - | buttons.forEach((button) => { | ||
| - | button.addEventListener(' | ||
| - | // ... | ||
| - | if (!panelIsOpen) { | ||
| - | panelElement.classList.add(' | ||
| - | button.setAttribute(' | ||
| - | } | ||
| - | }); | ||
| - | }); | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | **Bug: Doppeltes classList.add – Panel lässt sich nicht schliessen** | ||
| - | |||
| - | <WRAP round box 80% center> | ||
| - | <code js> | ||
| - | // ❌ classList.add(' | ||
| - | // → Panel wird immer geöffnet, nie geschlossen | ||
| - | buttons.forEach((button) => { | ||
| - | button.addEventListener(' | ||
| - | const panelElement = e.target.nextElementSibling; | ||
| - | const panelIsOpen = panelElement.classList.contains(' | ||
| - | |||
| - | buttons.forEach((andererButton) => { | ||
| - | andererButton.nextElementSibling.classList.remove(' | ||
| - | andererButton.setAttribute(' | ||
| - | }); | ||
| - | |||
| - | panelElement.classList.add(' | ||
| - | |||
| - | if (!panelIsOpen) { | ||
| - | panelElement.classList.add(' | ||
| - | button.setAttribute(' | ||
| - | } | ||
| - | }); | ||
| - | }); | ||
| - | |||
| - | // ✅ Nur innerhalb des if-Blocks | ||
| - | buttons.forEach((button) => { | ||
| - | button.addEventListener(' | ||
| - | const panelElement = e.target.nextElementSibling; | ||
| - | const panelIsOpen = panelElement.classList.contains(' | ||
| - | |||
| - | buttons.forEach((andererButton) => { | ||
| - | andererButton.nextElementSibling.classList.remove(' | ||
| - | andererButton.setAttribute(' | ||
| - | }); | ||
| - | |||
| - | if (!panelIsOpen) { | ||
| - | panelElement.classList.add(' | ||
| - | button.setAttribute(' | ||
| - | } | ||
| - | }); | ||
| - | }); | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | **Bug: Syntaxfehler in forEach – fehlende öffnende Klammer** | ||
| - | |||
| - | <WRAP round box 80% center> | ||
| - | <code js> | ||
| - | // ❌ Syntaxfehler: | ||
| - | // → Console: Uncaught SyntaxError: | ||
| - | buttons.forEach(andererButton) => { | ||
| - | andererButton.nextElementSibling.classList.remove(' | ||
| - | }); | ||
| - | |||
| - | // ✅ Korrekt | ||
| - | buttons.forEach((andererButton) => { | ||
| - | andererButton.nextElementSibling.classList.remove(' | ||
| - | }); | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | ==== Script-Position: | ||
| - | |||
| - | <WRAP round box 80% center> | ||
| <code html> | <code html> | ||
| - | <!-- ❌ Script im < | ||
| - | <!-- → document.querySelectorAll(' | ||
| < | < | ||
| < | < | ||
| Zeile 350: | Zeile 235: | ||
| </ | </ | ||
| < | < | ||
| - | <button class=" | + | |
| </ | </ | ||
| </ | </ | ||
| - | <!-- ✅ Script | + | === Script |
| - | <!DOCTYPE html> | + | |
| - | < | + | {{: |
| - | < | + | |
| - | <link href=" | + | |
| - | </ | + | |
| - | < | + | |
| - | <button class=" | + | |
| - | <script src=" | ||
| - | </ | ||
| - | </ | ||
| - | </ | ||
| </ | </ | ||
| Zeile 374: | Zeile 250: | ||
| Der Elements-Tab zeigt, was der Browser **tatsächlich** aus Ihrem Code gemacht hat – nicht was Sie geschrieben haben, sondern was nach dem Parsen und Rendern übrig bleibt. | Der Elements-Tab zeigt, was der Browser **tatsächlich** aus Ihrem Code gemacht hat – nicht was Sie geschrieben haben, sondern was nach dem Parsen und Rendern übrig bleibt. | ||
| + | |||
| + | {{: | ||
| ==== CSS live ausprobieren ==== | ==== CSS live ausprobieren ==== | ||
| Zeile 381: | Zeile 259: | ||
| - Rechts: Styles-Panel | - Rechts: Styles-Panel | ||
| - Eigenschaft anklicken und Wert ändern | - Eigenschaft anklicken und Wert ändern | ||
| - | - **Sofortiges Feedback** – ohne die Datei zu speichern | + | - Änderung wird direkt im Browser gerendert und sichtbar |
| Wenn der Look stimmt: dann erst in die CSS-Datei übertragen. | Wenn der Look stimmt: dann erst in die CSS-Datei übertragen. | ||
| <WRAP center round tip 80%> | <WRAP center round tip 80%> | ||
| - | Deaktivierte CSS-Regeln (durchgestrichen) bedeuten: eine andere Regel mit höherer Spezifität | + | Deaktivierte CSS-Regeln (durchgestrichen) bedeuten: eine andere Regel mit höherer Spezifität |
| - | </ | + | |
| - | + | ||
| - | ==== Der Computed-Tab ==== | + | |
| - | + | ||
| - | Wenn '' | + | |
| - | → Computed-Tab öffnen → dort steht der **berechnete Pixelwert**. | + | |
| - | + | ||
| - | Das erklärt, warum '' | + | |
| - | + | ||
| - | + | ||
| - | ===== Breakpoints setzen ===== | + | |
| - | + | ||
| - | Manchmal reicht '' | + | |
| - | + | ||
| - | **So geht' | + | |
| - | | + | |
| - | - Die JS-Datei links in der Dateiliste anklicken | + | |
| - | - Zeilennummer links anklicken → blauer Punkt = Breakpoint gesetzt | + | |
| - | - Seite neu laden oder Aktion ausführen → Code stoppt an dieser Stelle | + | |
| - | - Rechts sehen Sie alle aktuellen Variablenwerte | + | |
| - | + | ||
| - | **Navigieren: | + | |
| - | * **Step over** (F10): Nächste Zeile ausführen | + | |
| - | * **Step into** (F11): In eine Funktion hineinsteigen | + | |
| - | * **Resume** (F8): Weiter bis zum nächsten Breakpoint | + | |
| - | + | ||
| - | <WRAP center round info 80%> | + | |
| - | Für den Anfang reicht: Breakpoint setzen, einmal F10 drücken, Variablenwert rechts ablesen.\\ | + | |
| - | Den Rest lernen Sie automatisch, | + | |
| </ | </ | ||
| Zeile 431: | Zeile 280: | ||
| </ | </ | ||
| - | |||
| - | ===== Übungsaufgabe: | ||
| - | |||
| - | Der folgende Code enthält **4 absichtliche Bugs** – alle stammen aus echten Fehlern aus dem Unterricht. Öffnen Sie DevTools und finden Sie die Fehler, ohne den Code anzustarren. Benutzen Sie Console, Elements-Tab oder Breakpoints. | ||
| - | |||
| - | **HTML-Datei: | ||
| - | |||
| - | <WRAP round box 80% center> | ||
| - | <code html> | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | <script src=" | ||
| - | <link href=" | ||
| - | </ | ||
| - | < | ||
| - | <div class=" | ||
| - | <button class=" | ||
| - | <div class=" | ||
| - | <button class=" | ||
| - | <div class=" | ||
| - | </ | ||
| - | </ | ||
| - | </ | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | **JavaScript-Datei: | ||
| - | |||
| - | <WRAP round box 80% center> | ||
| - | <code js> | ||
| - | const buttons = document.querySelectorAll(' | ||
| - | |||
| - | buttons.forEach((button) => { | ||
| - | button.addEventListener(' | ||
| - | const panelElement = e.target.nextElementSibling; | ||
| - | panelElement.classList.toggle(' | ||
| - | }); | ||
| - | }); | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | **Tipps:** | ||
| - | * Bug 1: Erzeugt keinen Fehler – aber die Styles werden nicht geladen | ||
| - | * Bug 2: Erzeugt keinen Fehler – aber '' | ||
| - | * Bug 3: '' | ||
| - | * Bug 4: '' | ||
| - | |||
| - | <WRAP center round info 80%> | ||
| - | Schreiben Sie für jeden gefundenen Bug das **Debugging-Protokoll** aus: Was haben Sie beobachtet? Was war Ihre Hypothese? Wie haben Sie es geprüft? | ||
| - | </ | ||
| ===== Zusammenfassung ===== | ===== Zusammenfassung ===== | ||
| Zeile 488: | Zeile 286: | ||
| ^ Werkzeug ^ Wann einsetzen ^ | ^ Werkzeug ^ Wann einsetzen ^ | ||
| | **Formatter / Prettier** | Zuerst immer – Syntaxfehler, | | **Formatter / Prettier** | Zuerst immer – Syntaxfehler, | ||
| - | | **Console** | Wenn etwas passiert oder nicht passiert – Fehlermeldung lesen, '' | + | | **Console** | Wenn etwas passiert oder nicht passiert – Fehlermeldung lesen, '' |
| | **Elements-Tab** | Wenn das Layout falsch aussieht – CSS live anpassen, Computed-Tab prüfen | | | **Elements-Tab** | Wenn das Layout falsch aussieht – CSS live anpassen, Computed-Tab prüfen | | ||
| - | | **Breakpoints** | Wenn '' | ||
| </ | </ | ||