MODERNE ANWENDUNGEN ENTWICKELN MIT JAVASCRIPT - VON THOMAS BAHN, 18. JUNI 2018 OFFICECAMP 2018, GELSENKIRCHEN

Die Seite wird erstellt Horst-Adolf Heck
 
WEITER LESEN
MODERNE ANWENDUNGEN ENTWICKELN MIT JAVASCRIPT - VON THOMAS BAHN, 18. JUNI 2018 OFFICECAMP 2018, GELSENKIRCHEN
www.assono.de

Moderne Anwendungen entwickeln
mit JavaScript

von Thomas Bahn, 18. Juni 2018
OfficeCamp 2018, Gelsenkirchen
MODERNE ANWENDUNGEN ENTWICKELN MIT JAVASCRIPT - VON THOMAS BAHN, 18. JUNI 2018 OFFICECAMP 2018, GELSENKIRCHEN
Thomas Bahn
• Diplom-Mathematiker, Uni Hannover
• professionelle Web-Entwicklung seit
  30 Jahren
• regelmäßig Sprecher auf Konferenzen
  und Fachartikelautor
JavaScript
Die wahrscheinlich am meisten missverstandene Programmiersprache der Welt…
Historie (nicht wirklich)

• am Anfang: nur Spielereien im Browser
• heute: „ernsthafte“ Programmiersprache
  – im Browser (weiterhin)
  – auf dem Server (z. B. Node.js, SSJS)
  – eingebettet in Programme z. B. für Erweiterungen
• aktuell: ECMAScript 2015 (Spezifikation)
Voraussetzungen schaffen – Werkzeuge

• Editor/IDE
  – Texteditor reicht eigentlich, aber man kann auch mit Schaufeln einen Kanal ausheben
  – Microsoft Visual Studio Code (https://code.visualstudio.com/)
  – Atom (https://atom.io/)
• Browser
  – Google Chrome (https://www.google.de/chrome/),
  – Mozilla Firefox (https://www.mozilla.org/de/firefox/),
  – Microsoft Edge oder Internet Explorer
Voraussetzungen schaffen – Werkzeuge

• Entwicklerwerkzeuge im Browser: F12 drücken
• Firefox: Umschalt-F4 für JavaScript-Umgebung
• Chrome: Console bzw. Sources - Snippets
Online lernen und nachschlagen

• MDN Web Docs – JavaScript (https://developer.mozilla.org/de/Learn/JavaScript)
• MDN Web Docs – JavaScript reference
  (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference)
Grundlegendes

• Semikolon schließt Anweisung ab:
   Anweisung;
• Code-Block:
   {
     Anweisung1;
     Anweisung2;
   }
• // einzeiliger Kommentar
• /*
  mehrzeiliger Kommentar
  */
Variablentypen

• "loose typing", aber nicht untypisiert
• Es gibt genau folgende 6 7 Typen
   – String      Zeichenketten
   – Number      Zahlen (immer Gleitkomma)
   – Boolean     true oder false
   – Object      Objekt
   – null        Wert der für "Nichts" steht
   – undefined bisher noch nichts zugewiesen, daher noch undefiniert
   – Symbol (neu in ECMAScript 2015)
Ausgaben

• In die Konsole des Browsers:
   – console.log('text');
   – console.info('text');
   – console.warn('text');
   – console.error('text');
• alert('text');
• window.status = 'text';
Variablen

• var name;            Variablendeklaration
• var name = wert;     dito. mit Wertzuweisung
• let name = wert;     dito. mit Wertzuweisung, „block-scope“
• name = wert;         (erneute) Wertzuweisung
• const name = wert;   erste und letzte Wertzuweisung; Wert unveränderbar = konstant
Vergleichen

• Vergleichsoperatoren
  – <    kleiner als
  – = größer oder gleich
  – >    größer als
Operatoren

• Boolesche Operatoren
  – && logisches Und
  – || logisches Oder
  – !    logisches Nicht
• Arithmetische Operatoren
  – + Addition
  – -    Subtraktion
  – * Multiplikation
  – / Division
  – % Modulo-Operator (Rest bei Division)
Kurzschreibweisen

• Kurzschreibweisen
  – ++var --var     Variablenwert um 1 erhöhen bzw. erniedrigen und Anweisung ausführen
  – var++ var--     Anweisung ausführen und Variablenwert um 1 erhöhen bzw. erniedrigen
  – var += n        Kurzform für var = var + n, andere Operatoren analog
Bedingte Ausführung

• if (Bedingung) Anweisung;   Anweisung ausführen, wenn Bedingung true ergibt
• if (Bedingung) {            Anweisungsblock ausführen, wenn Bedingung true ergibt
        Anweisung1;
        ...
        AnweisungN
  }
• if (Bedingung) {            Anweisungsblock ausführen, wenn Bedingung true ergibt
        …
  } else {                    sonst zweiten Anweisungsblock ausführen
        …
  }
• switch (Ausdruck) {   Ausdruck berechnen und
    case label1:        Ausdruck mit label1 vergleichen
       Anweisungen …    ausführen, wenn gleich
       [break;]         ohne break; werden die nächsten Anweisungen auch ausgeführt
    case label2:        Ausdruck mit label2 vergleichen
       Anweisungen …    ausführen, wenn gleich
       [break;]         mit break; wird nach dem switch-Block weiter gemacht
    default:            wenn Ausdruck ungleich allen Labels ist
       Anweisungen …    dann diese Anweisungen ausführen
  }
for-Schleife

• die „normale“ For-Schleife
• typisch: gesteuert über eine Variable, die hoch oder herunter gezählt wird
• Format:
  for (Initialisierung; Bedingung; Inkrement/Dekrement) { Anweisungen … }
• alles 3 Positionen optional
• Initialisierung wird einmalig ausgeführt
• dann wird Bedingung vor erster und jeder weiteren Ausführung geprüft
• nach jeder Ausführung wird Inkrement/Dekrement ausgeführt
while-Schleife

• Format:
  while (Bedingung) {Anweisungen … }
• Bedingung wird vor der ersten und allen weiteren Ausführungen geprüft
• Wenn Bedingung true ergibt, werden die Anweisungen ausgeführt
do-while-Schleife

• Format:
  do {Anweisungen … } while (Bedingung);
• Block wird auf alle Fälle einmal ausgeführt
• Bedingung wird vor allen weiteren Ausführungen geprüft
• Wenn Bedingung true ergibt, werden die Anweisungen noch einmal ausgeführt
alle Schleifen: break und continue

• break;      Schleife verlassen und weiter mit erster Anweisung dahinter
• continue; aktuellen Durchlauf abbrechen und weiter mit nächstem Durchlauf
            (zum Schleifenanfang)
Arrays

• var wochentage = ['So', 'Mu', 'Di', 'Mi', 'Do', 'Fr', 'Sa'];
• Index des ersten Werts ist immer 0
• wochentage[3]               Array-Element am Index 3, ergibt hier: 'Mi'
• wochentage[1] = 'Mo';       setzt Array-Element am Index 1
• wochentage.length           Anzahl der Array-Elemente, ergibt hier: 7
• wochentage[wochentage.length] = 'gibbet nit';
                        neues Element hinten anfügen oder einfach mit
• wochentage.push('gibbet och nit');
for/in-Schleife

• Format:
  for (var wochentag in wochentage) { … wochentage[wochentag] … }
• wochentag ist nacheinander: 0, 1, 2, …
• durchläuft die Indexwerte des Arrays (oder die Indexmenge anderer iterierbarer Objekte)
for/of-Schleife

• Format:
  for (var wochentag of wochentage) { … wochentag … }
• wochentag ist nacheinander: 'So', 'Mo', 'Di', …
• durchläuft die Werte des Arrays (oder die Wertemenge anderer iterierbarer Objekte)
Funktionen

• 2 mögliche Wege, eigene Funktionen zu definieren (es gibt noch mehr):
  function summe(var summand1, var summand2) {
       return summand1 + summand2;
  }
  var summe = function (var summand1, var summand2) {
       return summand1 + summand2;
  }
• Aufruf:
  console.log(summe(1, 2))      ergibt natürlich: 3
• Funktionen sind Objekte, die auch in Variablen gespeichert und als Parameter bzw.
  Rückgabewerte übergeben werden können.
Objekte nutzen

• Objekte haben wir bereits mehrfach benutzt:
  – wochentage.length     greift auf Attribut length des Arrays wochentage zu
  – wochentage.push(…) führt Methode push des Arrays wochentage aus
  – console.log(…)        führt Methode log des Objekts console aus
• Weitere Objekte und ihre Nutzung:
  – Math.PI                      ergibt: 3.141592653589793
  – jetzt = new Date();
    console.log(jetzt.getDay()); ergibt: 1 (weil/wenn heute Montag ist)
Objektliterale

• Objekte kann man als Literal direkt im Quelltext definieren, z. B.
  var person = {
      vorname: 'Max',
      nachname: 'Mustermann',
      alter: 55,
      ganzer_name: function() { return this.vorname + ' ' + this.nachname; }
  }
• vorname, nachname und alter sind Attribute, ganzer_name eine Methode des Objekts,
  das in der Variable person gespeichert wird.
selbsterstellte Objekte nutzen

• console.log(person.vorname);               ergibt: Max
• console.log(person. ganzer_name());        ergibt: Max Mustermann
• person.vorname = 'Erika';                  (er)setzt den Vornamen
• Alle Attribute sind „öffentlich“, also komplett von außen zu lesen und zu ändern.
• Alle Methoden sind ebenfalls „öffentlich“, also von außen aufzurufen
• this verweist auf Kontext des aktuellen Objekts
Kontexte

• eine Besonderheit von JavaScript sind die Kontexte
• jedes Objekt hat einen eigenen Kontext
• Funktionen sind Objekte…
• Es gibt einen globalen Kontext (im Browser ist das der Kontext des window-Objekts).
• Löst der JavaScript-Interpreter einen Namen auf, geht er los bei lokalen
  Variablen/Parametern, dann der Kontext des aktuellen Objekts, dann der Kontext des
  übergeordneten Objekts, dann … , schließlich der globale Kontext.
JavaScript in HTML-Seiten einbinden

• direkt:
  
      console.log('Hallo Welt!');
  
• über eine Datei:
  
• JavaScript-Datei darf nur JavaScript, kein HTML enthalten
• type-Attribut type="text/javascript" überflüssig, da JavaScript Vorgabesprache ist
JavaScript in HTML-Seiten einbinden (forts.)

• falls JavaScript deaktiviert ist, wird  ausgewertet:
  Wenn Sie JavaScript aktiviert hätten…
• Einbindung von -Elementen wegen der Performance am besten direkt von dem
  schließenden -Tag
• Stößt der Browser auf ein -Element, wird es ggf. geladen und ausgeführt. Das
  Laden und Rendern der Seite wird solange pausiert.
• Das JavaScript im -Element (oder das von diesem geladen wird) kann nur auf den
  Teil der Seite zugreifen, der bereits gerendert ist.
Benutzerinteraktion

• modale Dialoge:
  – alert('Text');                   kann nur mit OK geschlossen werden
  – confirm('Text');                 OK gibt true zurück, Abbrechen false
  – prompt('Text', 'Vorgabewert');   eingegebener Text oder null beim Abbrechen
window-Objekt

• Im Browser ist window das Top-Level-Objekt
• Scheinbar „globale“ Funktionen und Variablen sind meist Methoden und Attribute des
  windows-Objekts.
• öffnet neues Fenster:
  window.open('https://www.assono.de', 'Titel', 'width=320,length=220,scrollbars=yes');
• schließt das aktuelle Fenster:
  window.close()
window.location-Objekt

• window.location gibt Zugriff auf aktuellen „Ort“
   – console.log(window.location.href);                 gibt URL der aktuellen Seite aus
   – window.location.href = 'https://www.assono.de‘;    lädt andere Seite (mit Historie)
   – window.location.replace('https://www.assono.de'); lädt andere Seite (ohne Historie)
window.navigator-Objekt

• window.navigator gibt Zugriff Browser-Informationen
  – window.navigator.userAgent             Name und Version des Browsers
  – window.navigator.language              oberste einstellte Sprache, z. B. "en-US"
  – window.navigator.platform              aktuelle Plattform, z. B. "Win32"
Geolocation-API

• Wo bin ich?
  function printPosition(pos) {
      console.log('geogr. Breite: ' + pos.coords.latitude +
                   ', geogr. Länge: ' + pos.coords.longitude);
  }
  window.navigator.geolocation.getCurrentPosition(printPosition);
• ergibt in der Nähe von Kiel:
  geogr. Breite: 50.1100897, geogr. Länge: 8.6822492
document-Objekt

• document (genauer: window.document) gibt Zugriff auf die aktuell anzeigte Seite
• DOM = Document Object Model; Repräsentation der Seite als Objekt-Baum
• durchhangeln oder direkter Zugriff über die ID eines Elements:
  var ersterAbsatz = document.getElementById('ersterAbsatz');
• oder über Arrays und die bekannte Position von Elementen (nicht machen!):
  var formular = document.forms[0];
  formular.elements[0].value = 'ich tue mal so als ob';
Elemente im DOM

• praktisch alle Eigenschaften lassen sich dynamisch verändern
• ersterAbsatz.style.color = 'red';
• ersterAbsatz.innerText = 'Wahnsinn, es funktioniert!';
Ereignisse behandeln

• Benutzeraktionen lösen Ereignisse aus, z. B. wenn der Benutzer auf eine Schaltfläche
  klickt oder ein Eingabefeld verlässt
• Beispiel:
  Klick mich
• so wird es schnell unübersichtlich und schlecht wartbar, besser trennen
Ereignisse behandeln (forts.)

• Beispiel mit vorher definierter Funktion:

   function kitzeln(buttonId) {
       document.getElementById(buttonId).innerText='ich bin kitzelig';
   }

Klick mich
• Fortgeschrittene Techniken entkoppeln noch weiter…
Textfelder

• HTML
  
• JavaScript
  var textFeld = document.getElementById('eingabefeldEinzeilig');
  if (textFeld.value == '') { … }// Feld ist leer
Checkboxen

• HTML
  Ich bin glücklich
• JavaScript
  var checkboxFeld = document.getElementById('happy');
  if (checkboxFeld.checked) { … }
Auswahllisten

• HTML
  
      -- wählen Sie ihre Automarke --
      Audi
      …
  
• JavaScript
  var optionslistFeld = document.getElementById('optionlist');
  if (optionslistFeld.selectedIndex == 0) { … }
  var selectedCar = optionslistFeld.options[optionslistFeld.selectedIndex].text;
Radiobuttons

• HTML
  Ich bin ein Mann
  Ich bin eine Frau
• JavaScript
  – leider etwas komplizierter…
  – jedes Element hat das Attribut checked, sodass man alle durchlaufen muss, obwohl
    maximal eines ausgewählt sein kann
Radiobuttons (forts.)

• mit einer kleinen Hilfsfunktion geht es wieder einfach:
  function getCheckedRadioValue(radioGroupName, defaultValue) {
       var radioButtons = document.getElementsByName(radioGroupName);
       for (var i = 0; i < radioButtons.length; i++) {
           if (radioButtons[i].checked)
                return radioButtons[i].value;
       }
       return defaultValue; // keine Option gewählt => nimm die Vorgabe
  }
  var selectedGender = getCheckedRadioValue('gender', null);
Versteckte Felder

• HTML
  
• JavaScript
  var verstecktesFeld = document.getElementById('verstecktesFeld');
  verstecktesFeld.value = window.navigator.userAgent;
Validierung vor dem Abschicken (vor HTML5)

• HTML
  
• JavaScript
  function validateForm() {
      var textFeld = document.getElementById('eingabefeldEinzeilig');
      if (textFeld.value == '') { // Feld ist leer
           alert('Das einzeilige Eingabefeld ist leer. Ändere das gefälligst!');
           return false; // Eingabe nicht valide
      }
      return true; // Eingabe valide
  }
Aufgabe: Vokabeln lernen

• Vokabeln deutsch-englisch in einem Array von Objekten als Literal definieren
• kleines HTML-Formular mit
  –  für deutsches Wort, Eingabefeld für Versuch und  für englisches Wort
  – Button zum „Aufdecken“, also das richtige Wort im unteren  einsetzen
  – Button „Nächste Vokabel“, der das nächste Wort im oberen  einsetzt, das Eingabefeld
      und den unseren  leert
• Beim Start das erste deutsche Wort im oberen  einsetzen
• Fertig? Vergleiche Eingabe und richtige Übersetzung, zähle mit und stelle Anzahlen für Versuche,
  Erfolge und Fehler dar
• Fertig? Ergänze Objekt um entsprechende Zähler für Erfolge und wiederhole bis 5x richtig
• Fertig? statt Wortpaare immer in gleicher Reihenfolge darzustellen, bring Zufall ins Spiel
Sie können auch lesen