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:40] – 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) | | ||
| </ | </ | ||
| Zeile 71: | Zeile 72: | ||
| {{: | {{: | ||
| {{: | {{: | ||
| + | {{: | ||
| Für VS Code brauchen Sie zwei separate Extensions, um dasselbe Niveau wie WebStorm zu erreichen: | Für VS Code brauchen Sie zwei separate Extensions, um dasselbe Niveau wie WebStorm zu erreichen: | ||
| Zeile 80: | Zeile 82: | ||
| 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. | ||
| - | |||
| - | <WRAP center round important 80%> | ||
| - | Prettier erkennt **keine** fehlenden Dateiendungen und **keine** falschen Anführungszeichen. Dafür brauchen Sie HTMLHint. | ||
| - | </ | ||
| **HTMLHint** prüft die HTML-Struktur und meldet typische Fehler wie falsche Anführungszeichen: | **HTMLHint** prüft die HTML-Struktur und meldet typische Fehler wie falsche Anführungszeichen: | ||
| Zeile 91: | Zeile 89: | ||
| <WRAP center round info 80%> | <WRAP center round info 80%> | ||
| - | **Hinweis | + | **Hinweis: |
| </ | </ | ||
| ==== Typische Fehler, die diese Tools erkennen ==== | ==== Typische Fehler, die diese Tools erkennen ==== | ||
| - | **Fehlende Dateiendung** (WebStorm & HTMLHint, nicht Prettier): | + | **Falsche Anführungszeichen** (WebStorm & HTMLHint): |
| - | + | ||
| - | <WRAP round box 80% center> | + | |
| - | <code html> | + | |
| - | <!-- ❌ Dateiendung fehlt – Browser findet die Datei nicht, kein Console-Fehler --> | + | |
| - | <link href=" | + | |
| - | <script src=" | + | |
| - | + | ||
| - | <!-- ✅ Korrekt --> | + | |
| - | <link href=" | + | |
| - | <script src=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | **Falsche Anführungszeichen** (WebStorm & HTMLHint, nicht Prettier): | + | |
| <WRAP round box 80% center> | <WRAP round box 80% center> | ||
| Zeile 123: | Zeile 107: | ||
| <WRAP center round important 80%> | <WRAP center round important 80%> | ||
| - | **Vorsicht beim Kopieren aus Moodle oder Word:** Textverarbeitungsprogramme ersetzen gerade Anführungszeichen ('' | + | **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). | Fügen Sie kopierten Code immer als **Plain Text** ein: **Cmd+Shift+V** (Mac) / **Ctrl+Shift+V** (Windows). | ||
| </ | </ | ||
| - | **Tippfehler in CSS-Eigenschaften** (WebStorm & Stylelint, nicht Prettier): | + | **Tippfehler in CSS-Eigenschaften** (WebStorm & VS Code): |
| <WRAP round box 80% center> | <WRAP round box 80% center> | ||
| Zeile 143: | Zeile 127: | ||
| } | } | ||
| </ | </ | ||
| + | |||
| + | {{: | ||
| + | // | ||
| </ | </ | ||
| Zeile 198: | 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 207: | Zeile 194: | ||
| </ | </ | ||
| - | {{: | + | {{: |
| **Was passiert:** | **Was passiert:** | ||
| Zeile 232: | 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 368: | Zeile 235: | ||
| </ | </ | ||
| < | < | ||
| - | <button class=" | + | |
| </ | </ | ||
| </ | </ | ||
| - | <!-- ✅ Script | + | === Script |
| - | <!DOCTYPE html> | + | |
| - | < | + | {{: |
| - | < | + | |
| - | <link href=" | + | |
| - | </ | + | |
| - | < | + | |
| - | <button class=" | + | |
| - | <script src=" | ||
| - | </ | ||
| - | </ | ||
| - | </ | ||
| </ | </ | ||
| Zeile 392: | 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 399: | 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 449: | 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 506: | 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 '' | ||
| </ | </ | ||