Fragen zu HTML5 und Co beantwortet 23 – Semikolons, Flexbox-Breiten, Formulare

nnn

nWieder haben mich viele neue Fragen zu HTML5, CSS3 und JavaScript über die diversen Kanäle erreicht. Dass es nicht zu mehr Blogposts kommt, ist allein meine Schuld … aber genug gejammert, ran an die neusten Leserfragen!n

nnnnn

Unterschied width/flex-basis

n

n

nWas ist bei einem Flexbox-Layout der Unterschied zwischen width und flex-basis? Gibt es überhaupt einen?n

n

n

nBeim Bau eines 0815-Spaltenlayouts ist es so gut wie egal, ob man width oder flex-basis verwendet – bei der einfachen Anordnung von Boxen nebeneinander führen beide Eigenschaften zum gleichen Ergebnis. Allerdings gibt es durchaus Unterschiede, die je nach Use Case durchaus ins Gewicht fallen können:n

n

    n

  • Vielleicht offensichtlich, aber dennoch erwähnenswert: flex-basis funktioniert nur im Flexbox-Kontext, width greift hingegen immer. Wenn man eine wiederverwertbare Komponente gestaltet, die mal mit und mal ohne Flexbox verwendet werden soll, ist das ein Argument für width.
  • n

  • Der Effekt von flex-basis ist von der gewählten flex-direction abhängig. Während width immer die horizontale Ausdehnung eines Elements steuert, kann flex-basis, wenn flex-direction auf column oder column-reverse steht, für die Höhe zuständig sein.
  • n

  • Während width auch bei absolut positionierten Elementen funktioniert, ist das bei Flex-Items nicht der Fall
  • n

  • Die praktische Abkürz-Eigenschaft flex fasst flex-basis mit flex-shrink und flex-growzusammen. Für width gibt es nichts Entsprechendes.
  • n

n

nHier eine kleine Demo der Gemeinsamkeiten und Unterschiede.n

nnnnn

Semikolons nach Funktionsdeklarationen

n

n

nWarum muss ich in JavaScript bei Funktionsdeklarationen kein Semikolon verwenden? Ich weiß Semikolons sind optional, aber bei Funktionsdeklarationen sehe ich so gut wie nie Semikolons. Warum ist das so?n

n

n

nDie ECMAScript-Spezifikationen verlangen tatsächlich nach Funktionsdeklarationen kein Semikolon (wenn eins da ist, stört es aber nicht). Zur Einordnung: das hier ist eine Funktionsdeklaration …n

n

function foo(){n  return 42;n}

n

n… und im Vergleich dazu ein Funktionsausdruck, nach dem man (wenn man mal die automatische Semikolon-Einfügung ignoriert) ein Semikolon haben sollte:n

n

var foo = function(){n  return 42;n};

n

nUnd warum ist das so? Semikolons trennen in JavaScript Statements voneinander. Funktionsdeklarationen sind aber keine Statements, sondern fallen in die Kategorie Declaration. Der beobachtbare Hauptunterschied ist, dass Funktionsdeklarationen evaluiert werden, bevor das Script tatsächlich ausgeführt wird. Das kann man daran erkennen, dass Funktionsdeklarationen aufgerufen werden können, bevor sie im Code definiert werden, was mit einem Funktionsausdruck nicht klappt:n

// Function Declarationnfoo(); // Klapptnfunction foo(){n  window.alert(23);n}nn// Function Expressionnbar(); // Klappt nichtnvar bar = function(){n  window.alert(42);n};

n

nLange Rede, kurzer Sinn: der Job, den Semikolons in JavaScript machen, wird von Funktionsdeklarationen nicht benötigt.n

nnnnn

Formulardaten lokal speichern

n

n

nIch möchte in ein Formular eingegebene Daten lokal speichern. Muss ich dafür ein jQuery-Plugin benutzen oder geht das auch mit HTML5-Bordmitteln?n

n

n

nMit FormData gibt es eine recht einfache API um die eigegebenen Daten aus einem Formular zu extrahieren. Das von new FormData(someFormElement) zurückgegebene Element hat eine entries() Methode, die einen Iterator über die Name-Wert-Paare der Formulardaten zurückgibt – und von da aus ist der Weg zum speicherbaren JSON nicht mehr weit:n

n

document.querySelector("input[value=Speichern]").addEventListener("click", () => {n  // Iterator mit [name, value]n  const data = new FormData(document.querySelector("form")).entries();n  // Daten als Objekte in einem Arrayn  const serialized = Array.from(data, ([name, value]) => ({ name, value }));n  // JSON, bereit zum Speichern in DOM Storage!n  const json = JSON.stringify(serialized);n  console.log(json);n});

n

nSo einfach kann es sein! Wichtig ist: FormData-Objekte können ohne Serialisierung direkt von XMLHttpRequest.send() verschickt werden und die IndexedDB kann zumindest die aus dem Iterator erzeugten Arrays speichern, ganz ohne JSON.n

nnnnn

Warum funktioniert mein Custom Error nach dem Submit-Event nicht?

n

n

nIch habe ein Formular gebaut, das beim Submit-Event ein paar Dinge validiert und im Fehlerfall mit setCustomValidity() HTML5-Validierungsfehler auf den Feldern auslösen soll. Das scheint aber in keinen Browser zu funktionieren. Was ist da los?n

n

n

nWenn man mit setCustomValidity() Felder als ungültig markieren möchte, muss man das vor dem Submit-Event erledigen. Der Sinn von setCustomValidity() ist das Festlegen des Fehler-Zustandes eines Feldes, nicht an Anzeigen der Fehlermeldung– das erledigt der Browser beim bzw. kurz vor dem Abschicken des Formulars selbst. Ein kleiner Auszuug aus dem Form submission algorithm von HTML5:n

n

n

nWhen a form element form is submitted from an element submitter (typically a button), optionally with a submitted from submit() method flag set, the user agent must run the following steps:n

n

    n

  1. If […] the constraint validation concluded that there were invalid fields and probably informed the user of this […] fire a simple event named invalid at the form element and then abort these steps.
  2. n

  3. […] then fire a simple event […] named submit, at form.
  4. n

n

n

nMan sieht: die Validierung findet vor dem Submit-Event statt. Deshalb sollte sollte setCustomValidity() dann passieren, wenn sich der Inhalt eines Feldes ändert (z.B. bei change– oder keyup-Events).n

nnnnn

Weitere Fragen?

n

nAll diese Fragen wurden mir per E-Mail oder Twitter gestellt und auch eure Fragen zu HTML(5), CSS(3), JavaScript und anderen Webtechnologien beantworte ich gerne! Einfach über einen der genannten Kanäle anschreiben oder gleich das komplette Erklärbären-Paket kommen lassen.n


Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert