JavaScript im Browser

JavaScript im Browser

im Browser verfügbare APIs:

Beispiele in der Browser-Konsole

DOM:

document.querySelector("body").textContent = "hello world";

HTML APIs:

alert('hello world');
setTimeout(() => {
  console.log('3 seconds have passed');
}, 3000);

Einbinden von JavaScript in HTML-Dokumente

Einbinden von JavaScript in HTML-Dokumente

Möglichkeiten:

intern, innerhalb des HTML-Codes:

<script type="module">
  console.log('hallo welt');
</script>

extern, in einer separaten Datei:

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

Bedeutung von type="module"

"ältere" Version des Einbindens von JS:

<script></script>

"moderne" Version:

<script type="module"></script>

Bedeutung von type="module"

Auswirkungen der Verwendung von type="module":

  • JS wird erst ausgeführt, wenn das HTML-Dokument vollständig geladen und bereit ist (JS-Ausführung ist "deferred")
  • JS wird im "strict mode" ausgeführt (verbietet z.B. nicht deklarierte Variablen)
  • Import-/Export-Funktionalität ist aktiviert

Document Object Model

Document Object Model

DOM (Document Object Model) = JavaScript-API für Interaktion mit dem HTML-Inhalt

Document Object Model

DOM Funktionalitäten:

  • Zugreifen auf HTML-Elemente (Querying)
  • Ändern von HTML-Elementen (Inhalt, Attribute)
  • Erstellen von HTML-Elementen
  • Reagieren auf Events (z.B. click)

DOM: Elemente abfragen / suchen

DOM: Elemente abfragen / suchen

Abfragen von HTML-Elementen:

  • document.getElementById()
  • document.getElementsByClassName()
  • document.getElementsByTagName()
  • document.querySelector()
  • document.querySelectorAll()
  • ...

DOM: Elemente abfragen / suchen

<div id="chat-popup">...</div>

Abfragen des DOM-Elements:

let element = document.getElementById('chat-popup');

äquivalent:

let element = document.querySelector('#chat-popup');

DOM: Elemente abfragen / suchen

Abfragen von mehreren Elementen:

let inputElements = document.querySelectorAll('input');

DOM: Elemente ändern

DOM: Elemente ändern

Themen:

  • Textinhalte eines Elements ändern
  • Attribute eines Elements ändern

Textinhalte ändern

  • element.textContent = ...
  • element.innerText = ...

Diese beiden Properties haben ähnliche Funktionalitäten

Textinhalte ändern

Beispiel: Ersetzen des body-Inhalts durch den Text "hello world"

let body = document.querySelector('body');

body.textContent = 'hello world';

Auf Attribute zugreifen

Zugriff auf HTML-Attribute: durch getAttribute und setAttribute oder durch eine entsprechende JS-Property

in HTML:

<a href="https://example.com">example</a>

Möglichkeiten in JS:

  • exampleLink.getAttribute("href")
  • exampleLink.setAttribute("href", "https://xyz.com")
  • exampleLink.href
  • exampleLink.href = "https://xyz.com"

HTML Attribute und JS Properties

Bei manchen HTML-Attributen weicht die entsprechende JS Property ab:

  • anderer Datentyp (Attribute sind immer Strings)
  • anderer Name

HTML Attribute und JS Properties

Attribut:

checkbox.setAttribute('checked', '');
checkbox.removeAttribute('checked');

DOM Property:

checkbox.checked = true;
checkbox.checked = false;

HTML Attribute und JS Properties

Das style-Attribut ist ein String, die style-Property ist ein Objekt:

element.setAttribute(
  'style',
  'color: #99aaff; padding: 4px;'
);
element.style.color = '#99aaff';
element.style.padding = '4px';

HTML Attribute und JS Properties

Zum class-Attribut gibt es die Properties className und classList

element.setAttribute('class', 'btn btn-primary');
element.className = 'btn btn-primary';

element.classList.add('important');

DOM: Elemente erstellen und anhängen

DOM: Elemente erstellen und anhängen

  • document.createElement()
  • element.append(...)
  • element.remove()
  • element.innerHTML

Elemente erstellen und anhängen

Beispiel: Erstellen eines Paragraphen mit einem Link

Vorlage:

<p>
  I'm learning <a href="https://example.com">JavaScript</a>.
</p>
let p = document.createElement('p');

let link = document.createElement('a');
link.href = 'https://example.com';
link.innerText = 'JavaScript';

p.append("I'm learning ", link, ".");

Das neue Element (p) kann in das bestehende Dokument eingefügt werden.

Elemente erstellen und anhängen

vorheriges Beispiel mit innerHTML:

let p = document.createElement('p');
p.innerHTML =
  'I\'m learning <a href="https://example.com">JavaScript</a>.';

Elemente erstellen und anhängen

Warum nicht immer innerHTML verwenden?

  • kann ein Angriffsziel sein (Code Injection / XSS)
  • Event-Listener können nicht hinzugefügt werden

Gefahren von innerHTML

Die Verwendung von innerHTML ist gefährlich, wenn Inhalte von Benutzern bereitgestellt werden.

Beispiel: ein böswilliger Benutzer hat sich mit folgenden Daten registriert:

  • Vorname: John
  • Nachname: Doe
  • Spitzname: <script>prompt("Enter your credit card number:")</script>

Wenn wir innerHTML verwenden, um den Spitznamen für andere Benutzer anzuzeigen, wird das Script in deren Browsern ausgeführt.

Bemerkung: die Verwendung von textContent bzw. innerText ist nicht gefährlich

Gefahren von innerHTML

Möglichkeiten, um Angriffe zu verhindern:

Vermeiden von innerHTML

oder

"escapen" von Inhalten, die aus unsicheren Quellen kommen

Gefahren von innerHTML

"Escapen" von Inhalten:

unsicherer String: <script>...</script>

"escaped" string mit HTML Entities: &lt;script&gt;...&lt;/script&gt;

Ãœbungen

  • Erstelle ein Schachbrett
  • Erstelle eine statische Todo-Liste

DOM: Events

DOM: Events

we can react to user interaction and other events, e.g.:

  • clicking / pressing on an element
  • moving the mouse over an element
  • typing in an input field
  • submitting a form
  • ...

DOM: Events

we can add functions as "event listeners":

let button = document.querySelector('#my-button');

button.addEventListener('click', () => {
  console.log('click event triggered on button');
});

DOM: Events

example: click counter - displaying a number in a div that is incremented when a button is clicked

let counterDisplay = document.createElement('div');
counterDisplay.textContent = '0';
let counterButton = document.createElement('button');
counterButton.textContent = 'increment';

counterButton.addEventListener('click', () => {
  counterDisplay.textContent =
    Number(counterDisplay.textContent) + 1;
});

document
  .querySelector('body')
  .append(counterDisplay, counterButton);

DOM: Events

event names:

  • click (can be triggered by any HTML element)
  • input (is triggered when the value of an input field is changed)
  • submit (for forms)
  • mouseenter (when the mouse cursor enters an element)
  • ...

see https://www.w3schools.com/jsref/dom_obj_event.asp for a long list

DOM: Events

exercise: Create an HTML file with various elements that have event listeners. Whenever an event occurs, log it to the console.

example output in the console:

button1: mouseenter
button1: click
button1: mouseleave
textbox1: mouseenter
textbox1: click
textbox1: input
textbox1: input
textbox1: mouseleave

DOM: Event objects

When an event occurs, we can access its corresponding Event object in JavaScript:

myButton.addEventListener('click', (event) => {
  console.log('myButton was clicked');
  console.log('mouse button:', event.button);
  console.log('coordinates:', event.clientX, event.clientY);
});

DOM: Events

examples:

  • game: click the box

DOM: forms and form events

Example: todo list

Web components

Web components

Web components = benutzerdefinierte Elemente: Können mittels JavaScript erstellt und wie reguläre HTML-Elemente verwendet werden

Web components

Beispiel: Fußzeile, die auf mehreren Seiten verwendet werden kann

<my-footer></my-footer>

Web components

Beispiel: Elemente, die eine Navigationsleiste bilden

<my-navbar>
  <my-logo></my-logo>
  <my-navbar-item>
    <a href="...">Startseite</a>
  </my-navbar-item>
  <my-navbar-item>
    <a href="...">Ãœber uns</a>
  </my-navbar-item>
</my-navbar>

Web components

Beispiel: Kartenansicht mit verschiedenen Konfigurationsoptionen

<my-map-view lat="48.2" lon="17.5" zoom="8"></my-map-view>

Web components

Beispiel: E-Mail-Liste

<my-email-list>
  <my-email from="..." to="..." title="..."></my-email>
  <my-email from="..." to="..." title="..."></my-email>
</my-email-list>

Web components: Funktionalitäten

Relativ einfach zu implementieren:

  • benutzerdefinierte Stile mit "Scoping"
  • Inhalte an Elemente übergeben (Slots)
  • Daten über statische Properties übergeben
  • Benutzerdefinierte Ereignisse (z.B. benutzerdefinierter Tastendruck, Wertänderung, andere Interaktionen)

Komplizierter (ohne zusätzliche Tools):

  • Komponenten, die sich im Laufe der Zeit ändern (z.B. aufgrund von sich ändernden Eigenschaften oder Benutzerinteraktionen)

Debuggen im Browser

Debuggen im Browser

debugger Statement

Debuggen im Browser

Breakpoints:

  • setzen von Breakpoints
  • Aktivieren / Deaktivieren von Breakpoints

Debuggen im Browser

Manuell weiterspringen:

  • play / pause
  • step over / Schritt darüber: in die nächste Zeile
  • step into / Schritt hinein: einem Funktionsaufruf folgen
  • step out / Schritt heraus: aktuellen Funktionsaufruf verlassen

Debuggen im Browser

Beobachten von Variablen

JavaScript: Drag and drop

Themen

  • Drag and drop
  • JavaScript Wiederholung / Vertiefung

Vorschau: Resultate

Vorwissen / Wiederholung

  • for ... of
  • Template-Strings
  • Pfeilfunktionen
  • getElementById / getElementsByClassName / querySelectorAll
  • addEventListener
  • innerText / innerHTML
  • preventDefault

Drag and drop

  • Drag and drop von Elementen innerhalb eines HTML-Dokuments (in ein anderes Element hinein)
  • Drag and drop von Elementen außerhalb des Browsers in das Dokument hinein (z.B. Text in ein Eingabefeld hinein)
  • Drag and drop von Elementen innerhalb des Browser nach draußen (z.B. Text in einen Texteditor)

Draggable

Elemente, die standardmäßig "draggable" sind:

  • ausgewählter Text
  • Bilder
  • Links

Frage: praktische Anwendung? / Wohin können wir ziehen?

Draggable

weitere Elemente "draggable" machen:

<div draggable="true">drag me!</div>

Drag-Events

welche Drag-Events gibt es?

und auf welchen Elementen werden diese ausgelöst?

Drag and drop events

Events des "bewegten" Elements:

  • dragstart
  • drag
  • dragend

Events des Ziels:

  • dragenter
  • dragover
  • dragleave
  • drop

Events

Ãœbung: mehrere "draggable" Elemente, die jeweils anzeigen, wie of sie schon "gedraggt" wurden

Drag and drop

"drop" auf Elementen erlauben:

bei "dragenter" und "dragover" Events des Ziels .preventDefault() aufrufen

function onDragEnter(event) {
  event.preventDefault();
}
function onDragOver(event) {
  event.preventDefault();
}

Drag and drop

auf "drop" reagieren:

function onDrop(event) {
  event.preventDefault();
  event.target.innerText += ' drop ';
}

Drag and drop

Übung: ein Element das mitzählt, wie oft auf es gedroppt wurde

Drag and drop: Daten mitgeben

Bei "drag start" Daten bestimmter Formate mitgeben:

function onDragStart(event) {
  event.dataTransfer.setData('text/plain', 'foo bar');
  event.dataTransfer.setData(
    'text/html',
    '<em>foo</em> bar'
  );
}

Beispiel: Draggen von HTML-Inhalten nach Word und in einen Plain-Text-Editor

Drag and drop: Daten mitgeben und wieder auslesen

bei "drag start" Daten eines Bestimmten Types mitgeben:

function onDragStart(event) {
  event.dataTransfer.setData('text/plain', 'foo');
}

bei "drag end" Daten auslesen:

function onDrop(event) {
  event.preventDefault();
  const data = event.dataTransfer.getData('text/plain');
}

Drag and drop: Daten übertragen

Übung: verschiedene Produkte, die in den Einkaufswagen gezogen werden können

Drag and drop: Elemente verschieben

Wir können auch ein ganzes Element durch drag and drop in ein anderes Element verschieben lassen

Drag and drop: Elemente verschieben

Verfahren: Der Dateneintrag, der übergeben wird, kann die ID des Elements sein - basierend darauf können wir das verschobene Element in sein neues Elternelement verschieben

Ãœbungen

  • Lotto - Generator
  • uhr
  • Todo-Liste
  • chessboard
  • Chat View