Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🤖 Table Auto Design

Das Problem

Wenn du den letzten Stand aus dem GitHub Repository nimmst, findest du eine Tabelle für die Benchmark-Übersicht.

Die Tabelle startet hier: index.html#L202

Design-Herausforderung

Obwohl die Tabelle funktioniert, hat sie ein fundamentales Problem: Die Breite der Diagramm-Säulen ist fest im HTML hinterlegt.

<p
  class="table-background-brown text-right mt-xxs mb-xxs pr-s py-xxs"
  style="width: 24%"
></p>

CSS hat hier seine Grenzen - Breiten und Höhen basierend auf "anderen" Elementen zu definieren, kann CSS nicht.

🎯 Ziele der dynamischen Tabelle

Wir möchten eine Tabelle, die folgendes kann:

  1. Automatische Berechnung: 100% Breite = höchster Wert, alle anderen prozentual abgeleitet
  2. Dynamische Anpassung: Ändern sich Werte, passt sich das Design automatisch an
  3. Wiederverwendbarkeit: Tabelle kann kopiert und mit neuen Werten verwendet werden

JavaScript Setup

Grundlagen JavaScript einbinden

Informationen zum Einbinden findest du auf SelfHTML.

Unser Ansatz:

  • Script am Ende der Seite laden (bessere Performance - First Contentful Paint)
  • Module-System für strukturierte Code-Organisation

Ordnerstruktur erstellen

Erstelle einen javascript Ordner mit folgenden Dateien:

javascript/
├── main.js
└── tables.js

JavaScript verknüpfen

1. In main.js das tables.js importieren:

import "./tables.js";

2. Am Ende von index.html (vor </body>):

<script src="javascript/main.js" type="module"></script>
</body>

💡 Wichtig: type="module" ermöglicht das Importieren anderer Scripts

✅ Test der Einbindung

In tables.js einfügen:

console.log("tables.js loaded");

Testen:

  1. index.html über LiveServer öffnen
  2. Chrome DevTools → Console
  3. Seite neu laden

Du solltest den Text sehen! 🥳 Klick rechts auf das Script-Link - es führt direkt zur Datei. Console log


DOM-Manipulation

Das Document Object Model (DOM)

Der Browser stellt JavaScript das DOM zur Verfügung - eine JavaScript-Repräsentation des gesamten HTML. Über diese Schnittstelle lassen sich Inhalte auslesen und manipulieren.

Elemente finden mit querySelectorAll

document.querySelectorAll("[selector]");

Findet alle Nodes mit dem angegebenen Selektor. Mehr dazu: MDN querySelectorAll


Data-Attribute for the Win

Das Problem lösen

Problem: Suche nach div findet zu viele unnötige Elemente.
Lösung: Data-Attribute

Vorteile von Data-Attributen:

  • Werden von Screenreadern ignoriert
  • Stören HTML-Struktur minimal
  • Geben JavaScript mehr "Wissen"

Tabelle markieren

Tabellen-Container markieren: Dies ist ein neues div Element welches um die bestehende Tabelle erweitert werden muss. Achte darauf, dass du das </div> nach der Tabelle schliesst.

<div data-table-name="benchmark">
  <h4 class="font-20 mb-s">XP-Pen Magic Notepad - CPU Benchmark</h4>
  <!-- ... restliches HTML ... -->
  <p class="font-13 font-color-light">Score (higher is better)</p>
</div>

Jede Column markieren:

<p
  class="table-background-brown text-right mt-xxs mb-xxs pr-s py-xxs"
  data-table-column
>
  720
</p>

💡 Alternative: data-table-type statt data-table-name für verschiedene Tabellentypen


JavaScript-Implementierung

1️⃣ Tabellen finden

document.querySelectorAll("[data-table-name]").forEach((table) => {
  // Code für jede Tabelle
});

Foreach siehe foreach Erklärung

2️⃣ Spalten finden und höchsten Wert ermitteln

Jetzt haben wir das Tabellen Element und können innerhalb wiederum all unsere Spalten finden. Wieso brauchen wir das? Damit die Breite der Spalten stimmt, müssen wir zuerst den höchsten Wert finden. Denn dieser bestimmt 100%. Davon abgeleitet können wir dann berechnen, wie viel % Breit die Spalte sein sollte.

Zuerst suchen wir uns alle columns. Danach gehen wir durch alle Spalten durch und merken uns den höchsten Wert. Dass kannst du mit einer lokalen Variable machen. Diese muss mit let definiert sein, wenn du den Werte anpassen willst. Ist der Wert Schreibgeschützt kannst du const nutzen. In unserem Fall brauchen wir let da wir den Wert neu schreiben, wenn er grösser als der vorherige ist.

document.querySelectorAll("[data-table-name]").forEach((table) => {
  
  // neuer Code
  const columns = table.querySelectorAll("[data-table-column]");

  let columnWidest = 0;
  columns.forEach((col) => {
    const colWidth = Number(col.innerText);
    if (colWidth > columnWidest) {
      columnWidest = colWidth;
    }
  });
  // neuer Code
  
});

Erklärung:

  • col.innerText: Nur Text, keine HTML-Tags oder Leerzeichen
  • Number(): Konvertiert Text zu Zahl für Vergleiche
  • Optional: trim() für Leerzeichen entfernen

3️⃣ Breiten berechnen und setzen

document.querySelectorAll("[data-table-name]").forEach((table) => {
  const columns = table.querySelectorAll("[data-table-column]");

  let columnWidest = 0;
  columns.forEach((col) => {
    const colWidth = Number(col.innerText);
    if (colWidth > columnWidest) {
      columnWidest = colWidth;
    }
  });
  // neuer Code
  columns.forEach((col) => {
    const colWidth = col.innerText;
    const width = (100 / columnWidest) * colWidth;
    col.style.width = `${width}%`;
  });
  // neuer Code
});

4️⃣ HTML-Style entfernen

Da JavaScript die Breite berechnet, kannst du das style="width: 24%" im HTML entfernen:

<p
  class="table-background-brown text-right mt-xxs mb-xxs pr-s py-xxs"
  data-table-column
></p>

Im Prinzip kannst du es als Rückfall drin lassen, sollte das JavaScript nicht geladen werden.


Erweiterte Version (Kürzer aber komplexer)

Kompakte Lösung

const maxWidth = Math.max(
  ...Array.from(columns, (col) => Number(col.innerText))
);
columns.forEach((col) => {
  col.style.width = `${(100 * Number(col.innerText)) / maxWidth}%`;
});

Erklärung der neuen Konzepte

Math.max()

MDN Math.max - Gibt den höchsten Wert zurück.

Array.from()

MDN Array.from - Erstellt Array aus Columns und deren innerText-Werten: [720, 789, 1023]

Spread Operator ...

MDN Spread Syntax - "Spreaded" Array-Elemente als einzelne Parameter:

  • Math.max([1,2,3]) ❌ funktioniert nicht
  • Math.max(...[1,2,3]) ✅ funktioniert → Math.max(1,2,3)

Template Literals

`${(100 * Number(col.innerText)) / maxWidth}%`;

Mit ${} können Variablen und Berechnungen direkt im String verwendet werden.


Fazit

AnsatzVorteileNachteile
AusführlichGut verständlich, lernfreundlichMehr Code
KompaktWeniger Code, eleganterErfordert mehr JS-Wissen

Lernempfehlung

  1. Beginne mit der ausführlichen Version
  2. Verstehe jeden Schritt
  3. Erweitere Wissen schrittweise zu kompakteren Lösungen

💡 AI & Google: Du wirst oft auf kompakte Varianten stoßen - je mehr du lernst, desto verständlicher werden sie!