Interaktivität (JavaScript)

Dieses Kapitel behandelt die Frontend-Entwicklung von Webanwendungen mit JavaScript. Dazu gehören die Einarbeitung in die grundlegenden Sprachprinzipien und -konstrukte (Syntax, Kontrollstrukturen, Schleifen, Funktionen etc.), in das Document Object Model (DOM) und das Arbeiten mit Event Handlern.

Zur Einführung

Nachdem die HTML-Auszeichung und CSS-Gestaltung der STURM-Webanwendung vollständig ist widmen wir uns nun der Frontendprogrammierung mit JavaScript. Maßgeblich für die weitere Beschäftigung und Praxis sind folgende Referenzseiten:

Innerhalb der Übung konzentrieren wir uns auf den Bereich der Frontendprogrammierung mit JavaScript im Kontext von Webanwendungen. Aus Zeitgründen ist ein tieferer Einstieg in JavaScript als Programmiersprache leider nicht möglich. Dieses Feld ist so umfangreich, dass es Gegenstand einer eigenen Veranstaltung sein müsste. Es sei jedoch festgehalten, dass sich JavaScript in den vergangenen Jahren zu einer der wichtigsten weborientierten Programmiersprachen entwickelt hat. Eine eingehendere Beschäftigung mit JavaScript ist daher eine äußerst sinnvolle Zeitinvestition.

Praxis mit JavaScript: Vorbereitung

Bevor Sie mit den Praxisaufgaben in der Sturm-App beginnen, wechseln Sie in den Übungsbranch, in dem die Sturm-App ohne JavaScript existiert:

git checkout no-javascript

Wenn Sie mit eine Übungsaufgabe beendet haben, können Ihre Arbeit jederzeit mit dem main-Branch auf https://gitlab.rlp.net/studiengang-digitale-methodik/modul-7/sturm-app/-/tree/main vergleichen und mit git checkout natürlich auch jederzeit lokal wieder den Branch wechseln.

Kurzüberblick

Folgende Tabelle gibt einen Überblick über wichtige Sprachkonzepte von JavaScript, die für einen Einstieg hilfreich sind. Die Einträge sind mit unterschiedlichen Kurzreferenzen zum schnellen Nachschlagen und Memorieren verlinkt. Das Spektrum der zur Verfügung stehenden Sprachfunktionen ist noch deutlich breiter. Für das erweiterte Nachschlagen empfiehlt sich die Sprachreferenz des Mozilla Developer Networks.

Bereich Konzepte
Versionsgeschichte, Implementierung ECMAScript 5 - 8, SpiderMonkey, V8, Chakra, Nitro
Codestruktur strict mode, variable declaration, constants declaration
Datentypen number, string, boolean, null, undefined, object, symbol
Interaktion prompt, confirm, alert
Operatoren arithmetical, assignment, bitwise, ternary, logical, comparison
Kontrollstrukturen if-else, switch, while, do-while, for, for-in, for-of
Funktionen function declaration, function expression, arrow functions, callbacks
Objekte literals, properties, built-in objects, object acces, this, constructor
Browserumgebung DOM, Events

JavaScript ist eine plattformübergreifende, schwach typisierte, multiparadigmatische, objektorientierte Skriptsprache (Interpretersprache). Multiparadigmatisch bedeutet, dass in JavaScript sowohl objektorientiert als auch funktional programmiert werden kann.

JavaScript gilt als ressourcenschonende und performante Programmiersprache und kann sowohl client- als auch serverseitig ausgeführt werden. Hierfür wird eine Laufzeitumgebung benötigt. Dies kann ein Browser sein, es gibt aber auch andere Laufzeitumgebungen. Alle modernen Webbrowser implementieren eine JavaScript-Engine. Je nach Browserversion ist zu prüfen, welche Version des JavaScript-Standards (ECMAScript) die jeweilige Browserengine implementiert.

Innerhalb einer Browserumgebung wird JavaScript häufig dazu verwendet, das DOM zu manipulieren, Nutzerdaten zu validieren, Daten in einer bereits geladenen Webseite (also nach abgeschlossenem Request-Response Zyklus) durch asynchrone Operationen zu aktualisieren (AJAX) sowie Cookies oder den lokalen Speicher des Browsers zu verwalten. JavaScript kann an jeder beliebigen Stelle in HTML eingebettet werden. Standardmäßig ist JavaScript in Browsern aktiviert, kann aber nutzerseitig deaktiviert werden.

Weitere Informationen

Einbindung

Clientseitiges JavaScript wird innerhalb von Webseiten mittels <script> eingebunden. Zwischen Script-Tags sollte umfangreicher Programmcode vermieden werden. Die bessere Praxis ist, den Code über das src Attribut des Script-Tags in eine externe Datei auszulagern.

// inzeilige Verwendung von JavaScript
<script>
alert('Hello World');
</script>

// Auslagerung in eine Datei
<script src="pfad/zur/datei.js"></script>

Info

Die getrennte Entwicklung und Pflege von HTML, JavaScript und CSS in jeweils eigenen Dateien ist eine Implementierung der sogenannten Separation of Concerns, ein in der Softwareentwicklung verbreitetes Designprinzip.

Wenn mit HTTP1.1 gearbeitet wird, sollte JavaScript erst nach dem Rendering einer Seite eingebunden werden. Dies kann zur Lade- und Renderinggeschwindigkeit der betreffenden Webanwendung beitragen. Sofern ein Script mit dem DOM arbeitet, “kennt” es zudem nur die Knoten bis zum Punkt der Einbindung, da der Browser das DOM sequentiell einliest. Dies kann zu Situationen führen, in denen ein Skript im <head> einer HTML-Datei nicht auf das <body> Tag zugreifen kann.

Eine einfache Lösung hierfür ist, das <script>-Tag für JavaScript - sofern möglich - “spät” in die Seite eingebunden werden, idealerweise vor dem schließenden <body> Element.

Alternativ kann JavaScript weiterhin im <head>-Bereich einer Seite eingebunden und das <script>-Tag mit dem Attribut defer verwendet werden. Damit wird die Ausführung des geladenen JavaScript-Codes verhindert, nachdem das DOM eingelesen wurde. Zu beachten ist, dass dies nur für ausgelagertes JavaScript gilt, Inline-Code wird weiterhin unmittelbar ausgeführt.

Praxis mit JavaScript-Grundfunktionen

Lernen Sie interaktiv einige Funktionalitäten von JavaScript kennen. Arbeiten Sie im Pair Programming (mit jeweils zwei oder ggf. drei Personen) die Aufgaben gemeinsam durch.

Einfache JavaScript-Sequenzen können Sie direkt über die Konsolen-Ansicht der Entwickler-Tools im Browser eingeben und mit RETURN/ENTER ausführen.

Screenshot: Ausführen eines alert-Scripts über die Browserkonsole (Firefox Developer Edition)

Quelle: Frodo Podschwadek

Alternativ können Sie auch die bei Frontend-Entwickler:innen beliebte Online-Plattform CodePen verwenden. Diese stellt eine komfortable Umgebung im Browser zur Verfügung, in der sich HTML, CSS und JavaScript testen lassen:


A. Syntax, Variablen, Konstanten, Operatoren

1) Geben Sie ein “Hello World!” in einem Browser-Dialogfenster aus.
2) Speichern Sie Ihren Namen in einer Variablen und geben Sie “Hello” in Verbindung mit Ihrem Namen aus.
3) Definieren Sie eine Konstante mit Ihrem Geburtsdatum und geben Sie diese aus.
4) Definieren Sie Variablen vom Typ number, string, boolean, undefined und null und geben Sie den Typ jeder Variable aus.
5) Verwenden Sie Operatoren zur Ausgabe folgender Anweisungen:

  • zwei Zeichenketten zusammenführen
  • eine Substraktion ausführen
  • Konversion einer numerischen Zeichenkette in eine Nummer
  • Inkrement und Dekrement einer Zahl
  • Kurznotation einer arithmetischen Operation

B. Bedingungen, Schleifen

6) Verwenden Sie die prompt()-Funktion um einen Dialog anzuzeigen, der nach dem Jahr der Erstveröffentlichung der HTTP-Spezifikation fragt. Die Antwort soll geprüft und ein Dialog geöffnet werden, der darüber informiert, ob die Antwort richtig oder falsch ist.
7) Speichern Sie Ihren Vor- und Nachnamen als Eigenschaft eines Objekts und geben Sie es aus.
8) Schreiben Sie einen switch, der auf Basis eines prompt() die Lieblingsprogrammiersprache abfragt und nach Eingabe einen Link auf die zur Sprache gehörende Wikipedia-Seite ausgibt. Planen Sie einen Standardfall für unbekannte Sprachen mit ein.
9) Schreiben Sie eine while Schleife, die von 5 - 10 zählt.
10) Schreiben Sie eine do..while Schleife, die zunächst 5 ausgibt und dann von 7 - 10 zählt.
11) Schreiben Sie eine for Schleife für die 7er-Reihe des Einmaleins mit Ausgabe.
12) Definieren Sie ein Objekt, das Namen der acht HTTP-Methoden enthält und nutzen sie eine for..in Schleife, um diese nacheinander auszugeben.
13) Schreiben Sie eine for..of Schleife mit dem Input ‘LAMP’, die nacheinander die vier Komponenten dieses Webstacks in aufgelöster Form ausgibt.

C. Funktionen

14) Schreiben Sie eine Funktion, die zwei Funktionsparameter addiert und zurückgibt. Notieren Sie diese Funktion als a) Funktionsdeklaration, b) Funktionsausdruck und c) in Arrow-Schreibweise.
15) Schreiben Sie eine Funktion, die unter Verwendung einer Callback-Funktion ‘Call Me Later Alligator!’ ausgibt. Hierbei soll der Teilstring ‘Later Alligator!’ in der Callback-Funktion festgelegt werden, der Teilstring ‘Call Me’ in der Hauptfunktion, welche die Callback Funktion aufruft.

D. Objekte

16) Erzeugen Sie ein Date-Objekt aus einem [ISO-Datumsstring}(https://de.wikipedia.org/wiki/ISO_8601) Ihrer Wahl.
17) Erweitern Sie das Personenobjekt aus Aufgabe 7 um eine Methode, mit der die Person etwas “sagen” kann.
18) Erzeugen Sie über eine Funktion ein Objekt, dass eine Zahl als Eigenschaft aufnimmt und innerhalb einer Methode diese Zahl mit einer Zufallszahl multipliziert (die Zufallszahl soll dabei ebenfalls ausgegeben werden).
19) Arbeiten Sie mit folgenden “nativen” Objekttypen:

  • iterieren Sie ein Array
  • wandeln Sie eine Zeichenkette in Großbuchstaben
  • runden Sie eine Zahl auf
  • finden Sie ein Muster in einem String.

E. DOM, Events

20) Geben Sie mittels console.log() das window-Objekt der Startseite der STURM-Webanwendung in der Laufzeitumgebung aus. Betrachten Sie sich die Eigenschaften dieses Objektes.
21) Untersuchen Sie die Eigenschaften des document-Objektes der STURM-Webanwendung. Identifizieren Sie die Eigenschaft, die alle CSS-Stylesheets enthält, iterieren Sie durch diese und geben Sie jeweils den Inhalt der href-Attribute aus.
22) Navigieren Sie durch das DOM der STURM-Webanwendung bis zur Hauptnavigation. Geben Sie dann den Text der Navigationselemente nacheinander in einer Schleife aus. Benutzen Sie zur Navigation firstElementChild, firstChild, lastElementChild und children sowie textContent.
23) Selektieren Sie alle Überschriften der Teaserboxen auf der Startseite und geben Sie den Inhalt der <h4> Tags aus.
24) Erzeugen Sie ein neues Listenelement, das einen Link enthält und fügen Sie dieses Element an das Ende der Hauptnavigation an.
25) Binden Sie ein Click-Event an den Link zur Homepage im Seitenkopf. Tritt das Event (der Click) ein, soll ein Dialogfenster mit einem Text ausgegeben werden.

(Lösungen)

Das DOM

Einen sehr häufigen browserseitigen Anwendungsfall von JavaScript stellt die Traversion und/oder die Manipulation des DOM (Document Object Model) dar. Das DOM repräsentiert die Elemente eines XML- oder HTML-Dokumentes in Form einer Baumstruktur. Hierbei gibt es folgende unterschiedliche Knotentypen:

  • Dokumentknoten (1 x pro Dokument)
  • Elementknoten (n x pro Dokument)
  • Attributknoten (n x pro Dokument)
  • Textknoten (n x pro Dokument)
  • Kommentarknoten (n x pro Dokument)

Das DOM wurde Mitte der 1990er Jahre maßgeblich durch die Entwicklung von JavaScript beeinflußt und standardisiert. Neben JavaScript hat die Entwicklung von XML als Daten-Austauschformat zwischen Anwendungen zur Standardisierung des DOM beigetragen.

Das DOM kann als Programmierschnittstelle begriffen werden, da es standardisierte Funktionen und Methoden zum Zugriff auf die Bestandteile eines XML/HTML-Dokumentes bereitstellt. Um das DOM für ein Dokument zu erzeugen wird das Markup zunächst durch einen DOM-Parser verarbeitet. Browser verfügen über eigene DOM-Parser. Daneben existiert aber auch eine Vielzahl von browserunabhängigen Parsern, mit denen XML/HTML-Dokumente in ein DOM überführt werden können.

Innerhalb des browserbasierten DOM sind mehrere grundlegende Objekte mit Methoden definiert, über die mittels JavaScript auf die Bestandteile des jeweiligen Dokumentes zugegriffen werden kann:

Grafik: JavaScript innerhalb der Laufzeitumgebung des Browsers

Quelle: The Modern JavaScript Tutorial

Noch aus der Anfangszeit der Standardisierung von JavaScript stammt das globale Objekt, das Zugriff auf globale Variablen und Funktionen bereitstellt. In Browserumgebungen stellt das window-Objekt das globale Objekt dar. Neben dem Zugriff auf globale Variablen und Funktionen kann es auch dazu genutzt werden, um die Existenz bestimmter Methoden und Objekte zu prüfen (bspw. ob ein XMLHttpRequest Objekt existiert).

Der eigentliche Zugriff auf die Bestandteile einer HTML-Seite mittels JavaScript erfolgt über das document-Objekt.

Neben dem document-Objekt existiert in browserbasierten Laufzeitumgebungen auch noch das BOM (Browser Object Model). Dieses stellt zusätzliche (teilweise browserspezifische) Funktionalitäten für den Zugriff mittels JavaScript bereit, bspw. das location-Objekt (enthält u.a. die aktuelle URL) oder das navigator-Objekt (enthält u.a. die Browseridentifikation).

Events

Bei einem DOM Ereignis (event) handelt es sich um eine Aktion, die auf einem Knoten des DOM ausgelöst wird (bspw. durch eine Nutzer:inneninteraktion oder den Abschluss des Ladevorgangs eines Dokumentes etc.). Für die Ereignisbehandlung bietet die DOM Spezifikation eine standardisierte API an. JavaScript-seitig werden hierfür die sogenannten event handler eingesetzt. Ein Handler kann dabei entweder direkt in einem HTML-Attribut definiert werden (Schema: handlername=“action()”), in einem externen Skript durch die Verwendung von Eigenschaften am jeweiligen DOM-Element (Schema: element.handlername) oder mittels eines event listeners (Schema: element.addEventListener(eventname, handlername [,phase])).

Die HTML-Attribut Deklaration eines Handlers sollte dabei nur sparsam eingesetzt werden, da hier nicht die Möglichkeit besteht, längeren JavaScript-Code auszuführen. Zudem vermischt diese Vorgehensweise die Zuständigkeiten in einer Webanwendung (HTML: Inhaltsstrukturierung, JavaScript: Programmlogik).

Die Deklaration eines Handles an einem DOM-Element hat den Nachteil, dass jedem DOM-Element nur ein Handler zugewiesen werden kann. Diese Beschränkung besteht bei der Deklaration von Handlern mittels der addEventListener-Methode nicht. Daher wird diese dritte Vorgehensweise für die meisten Entwicklungsszenarien als best practice empfohlen.

<!-- html attribut deklaration -->
<input id="button" type="button" value="Click me" onclick="alert('Thank you!')"/>

<!-- DOM element deklaration -->
<input id="button" type="button" value="Click me"/>

<script>
  const sayThanks = () => {
          alert('Thank you!')
        },
        button = document.getElementById('button')

  button.onclick = sayThanks
</script>

// event listener
<input id="button" type="button" value="Click me"/>

<script>
  const handler1 = () => {
          alert('Thank you!')
        },
        handler2 = () => {
          alert('Thank you again!')
        },
        button = document.getElementById('button');

  button.addEventListener('click', handler1); // Thank you!
  button.addEventListener('click', handler2); // Thank you again!
</script>
Praxis mit JavaScript: Ausklappbare Chronologie für die STURM-Briefe

Zur Verbesserung der Übersichtlichkeit der STURM-Webanwendung soll die nach Jahren gegliederte Chronologie ein- und ausklappbar gemacht werden. Im Ausgangszustand sind alle Brieflisten unterhalb der Jahre eingeklappt. Ein Klick auf das jeweilige Jahr öffnet die dazugehörige Liste. Ein erneuter Klick auf das gleiche Jahr klappt die Liste wieder ein. Mittels zweier Links unterhalb der Hauptüberschrift sollen alle Listen ein- und ausgeklappt werden können.

Um eine flüssige Animation zu erzeugen, sollten verschiedene Zustände über unterschiedliche CSS-Klassen realisiert und auch CSS-Transitions eingesetzt werden.

Hierfür können Sie die DOM-Elemente <div class="letters-wrapper"> verwenden, die bereits im Template briefe.html existieren. Legen Sie für diese Elemente entsprechende CSS-Styles an:

.letters-wrapper {
    height: 0;
    overflow: hidden;
    opacity: 0;
    position: relative;
    transition: all 0.5s ease-in-out;
}

.letters-wrapper.show {
    opacity: 1;
}

Bei erneutem Laden der Seite stellen Sie nun fest, dass die Brieflisten nicht länger sichtbar sind.

Legen Sie nun eine JavaScript-Datei mit dem Namen letters.js im Ordner templates/js an und binden Sie diese Datei auf der Seite ein. Entwickeln Sie darin nun das entsprechende JavaScript, um den oben beschriebenen Zustandswechsel zu bewirken.

Hinweis: Transitions funktionieren bei einem Wechsel zwischen CSS-Klassen nicht für Eigenschaften, für die der Wert auto verwendet wird, etwa bei height. Hier muss man ggf. den Wert, der sonst automatisch per auto vom Browser ermittelt würde, per JavaScript ermitteln und setzen. Wenn Sie also die CSS-Eigenschaft height für ein .letters-wrapper-Element an die Höhe der darin einbetteten Liste anpassen wollen, müssen Sie dafür zunächst die Höhe des entsprechenden .letters-Kindelementes ermitteln.

Praxis mit JavaScript: Klickvergrößerung der STURM-Digitalisate

Für die in den Brief-Detailansichten eingebundenen Digitalisate soll eine JavaScript-basierte, responsive Vergrößerungsmöglichkeit implementiert werden. Sofern mehrere Digitalisate auf einer Seite eingebunden sind, sollen diese in der Vergrößerung in Reihenfolge durchgeblättert werden können.

Die Detailansicht wird in einer sogenannten Lightbox dargestellt, einer dynamisch eingeblendeten halbtransparenten Ebene, die sich aus der Perspektive von Nutzer:innen über den eigentlichen Seiteninhalt legt. Das hierfür vorbereitete HTML finden Sie im Template lightbox.html. Binden Sie dieses Template mit einer {% include %}-Direktive am Ende des Templates base.html ein (jedoch vor dem JavaScript-Block).

Die Lightbox ist standardmäßig verborgen (das entsprechende CSS befindet sich in style.css). Ein zusätzliches Stylesheet namens lightbox.css wird im Template brief.html eingebunden und kann zusammen mit JavaScript verwendet werden.

Legen Sie nun eine Datei namens lightbox.js an, die Sie im Template brief.html einbinden. Schreiben Sie nun das entsprechende JavaScript, mit dem bei einem Klick auf eine der Thumbnails am rechten Rand einer Brief-Detailansicht der Wert des src-Attributes des Thumbnails für das <img>-Tag in der Lightbox gesetzt und die Lightbox dann sichtbar wird. Stellen Sie auch sicher, dass Nutzer:innen die Lightbox wieder schließen können.

Bibliotheken, Pakete und Frameworks

Für viele Anwendungsfälle von JavaScript gibt es inzwischen fertige Bibliotheken und Pakete, die als Open-Source-Software z.B. über npm verfügbar sind. Wie auch für Frameworks gilt auch für kleinere, spezalisierte Code-Bibliotheken, dass sie einerseits die Arbeit erleichtern und effizientere und sicherere Lösungsstrategien als selbstgeschriebener Code ermöglichen, andererseits aber zu Altlasten und Sicherheitsrisiken werden können, wenn sie von der betreffenden Community nicht mehr gepflegt werden. (Dieses Problem gibt es nicht nur bei JavaScript, für Composer-Pakete bei PHP und Python-Pakete gilt das gleiche.)

Grafik: Darstellung des generellen Risikos von Software-Abhängigkeiten

Quelle: XKCD

Für die grundlegende Bewertung der Qualität einer Bibliothek oder eines Paketes lohnt es sich, die dazugehörige npm-Seite und das öffentliche Repository bei GitHub oder GitLab auf folgende Kriterien hin anzusehen:

  • Wie viele Downloads hat das Paket? Eine hohe Anzahl an Downloads lässt darauf schließen, dass es weit verbreitet ist und zuverlässig funktioniert.
  • Wie viele Kontributoren gibt es? Je mehr Programmierer:innen zu einem Projekt beitragen, desto geringer das Risiko, dass es überraschend aufgegeben wird.
  • Wann wurde das Paket zum letzten Mal aktualisiert? Je länger dieser Zeitpunkt in der Vergangenheit liegt, desto größer das Risiko, dass das Projekt aufgegeben wird.
  • Von wie vielen anderen Paketen ist das Paket abhängig? Je mehr Abhängigkeiten bestehen, desto größer das Risiko, dass möglicherweise eines dieser Pakete aufgegeben wird.
  • Ist das Paket hinreichend gut dokumentiert?

Einige Beispiele für JavaScript-Bibliotheken sind:

  • axios: Request- und Response-Handhabung zwischen Browser und Server (oder, im Fall einer Node.js-Anwendung, zwischen unterschiedlichen Servern).
  • Day.js: Auslesen, Manipulation und Ausgabe von Datums- und Zeitformaten.
  • N3: Auslesen und Speichern von RDF-Daten im Browser.
  • GreenSock: Animationen im Browser.
  • three.js: Browserbasierte 3D-Darstellung.

Innerhalb der letzten zehn Jahre haben sich darüber hinaus zahlreiche leistungsstarke JavaScript-Frameworks entwickelt, mit denen sich komplette Webanwendungen auf Basis von Frontend-JavaScript realisieren lassen, z.B.

Aus der Perspektive des Projektmanagements ist es wichtig, sich über die Konsequenzen eines Einsatzes von Frameworks im Klaren zu sein. Einerseits kann die Einbindung eines Frameworks förderlich für die Entwicklungsgeschwindigkeit und die Codequalität in einem Projekt sein, da Frameworks meistens gute Konventionen mitbringen, denen die Entwickler:innen in einem Projekt folgen können. Andererseits führt die Einbindung eines Frameworks zu Abhängigkeiten im eigenen Code. Sollte ein eingesetztes Framework (manchmal unerwartet) nicht mehr weiterentwickelt werden, kann dies schnell zu einer Nachhaltigkeitsproblematik der Software im Projekt führen.

Ein weiterer zu bedenkender Punkt beim Einsatz eines Frameworks ist die zunehmende Abstraktion von Funktionalität auf Code-Ebene. Wichtige Funktionalitäten werden dabei häufig in das Framework (und somit auf eine abstraktere Ebene) verlagert. Kommt es dann zu unerwarteten Problemen, sind die betroffenen Funktionalitäten meistens tief innerhalb eines Frameworks implementiert und es kann mitunter schwierig werden, mit vertretbarem Zeitaufwand eine Lösung zu finden. Das Framework wird in solchen Fällen häufig zu einer black box.

Folgende Seiten bieten eine gute Übersicht über aktuelle JavaScript-Frameworks:

AJAX

Mit dem Akronym AJAX (Asynchronous JavaScript And XML) werden Ansätze in der Frontendprogrammierung beschrieben, bei denen Daten mit asynchronen HTTP-Requests von einer API angefordert werden. Das erlaubt z.B. einen schnelleren Seitenaufbau, weil viele Elemente einer Seite bereits im Browser gerendert werden können, während die Daten für die Inhalte noch bei einer API angefragt werden. Es ermöglicht auch interaktiven Austausch zwischen Browser und Server, ohne dass ein Reload der Seite nötig wird (wenn z.B. Formulardaten mit einem HTTP-Request mit JavaScript übertragen werden).

Praxis mit JavaScript: Interaktive Kartierung

“It’s APIs all the way down.” – Webentwickler:innen-Sprichwort

Auf der Übersichtseite des Ortsregisters soll eine neue Spalte mit einer interaktiven Karte eingeführt werden. Diese Karte stellt auf einer Open Street Map alle Orte dar, die in den Briefen genannt werden. Ein Klick auf einen Ortspunkt öffnet auf der Karte ein Dialogfenster sich der Link zum Normdatensatz (sofern vorhanden) und alle Folioangaben der zugehörigen Briefe befinden.

Wir erhalten die Daten für diese Karte aus einer RESTful API, die wir mit Hilfe der fetch-API von JavaScript ansprechen (Sie erinnern sich, das APIs in verschiedenen Zusammenhängen vorkommen; dies ist ein Beispiel dafür). Für die Kartendarstellung soll die JavaScript-Bibliothek Leaflet eingesetzt werden.

Finden Sie zunächst heraus, welche Daten Sie von der STURM-API erhalten. Sie benötigen für die Darstellug der Orte auf einer Karte sogenannte Geokoordinaten, die jeweils aus einem Wert für longitude (Längengrad) und latitude (Breitengrad) bestehen.

Machen Sie sich dann mit der Leaflet-API vertraut (noch eine API) und finden Sie heraus, wie Sie

  1. Eine Karte generieren,
  2. auf der Karte eine Reihe von Koordinaten markieren und
  3. die Markierungen bei klick weitere Informationen anzeigen lassen können.

Erstellen Sie eine Datei namens map.js und binden Sie diese im Template orte.html ein. Davor laden Sie noch die Leaflet-Bibliothek mit

<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>

Schreiben nun Ihren JavaScript-Code für die Karte.