Wertrückgabe in JavaScript (Wertrückgabe in JavaScript), Lektion, Seite 722802
https://www.purl.org/stefan_ram/pub/wertrueckgabe_javascript (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
JavaScript-Kurs

Die Ereignisbehandlung in JavaScript  unter Firefox 49 

Ereignisse

Bestimmte Vorgänge werden als Ereignisse  bezeichnet. Die JavaScript -Implementation kann auf solche Ereignisse reagieren, so daß sie bestimmte Reaktionen hervorrufen können, die teilweise vom Programmieren festgelegt werden können. Eine für ein Ereignis festgelegte Reaktionen nennen wir auch eine Ereignis-Behandlung.

Das Klick-Ereignis

Wird etwas angeklickt, so nennt man dies auch ein Klick-Ereignis.

Das Hinzufügen eines Ereignisempfängers

Eine Funktion die aufgerufen wird, wann immer ein bestimmtes Ereignis eintritt, nennen wir auch einen Ereignisempfänger.

Ein Ereignisempfänger kann mit Hilfe der Funktion »addEventListener« zu einem Ereignis hinzugefügt werden.

Main.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head><meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<title>Main</title><style type="text/css">

</style></head><body>

<p><a id="a" href="http://example.invalid">example</a></p>

<pre><code><script>/*<![CDATA[*/

a = window.document.getElementById( "a" );

a.addEventListener( "click", ()=> window.alert( "click" ) );

/*]]>*/</script></code></pre></body></html>

Protokoll
[click]
Navigation zu http://example.invalid

Im obigen Programm wird die Funktion »addEventListener« des Verzeichnisses »a«, welches das a-Element der Webseite repräsentiert, aufgerufen. Das erste Argument »"click"« gibt den Typ des Ereignisses an, für das der Empfänger hinzugefügt werden soll. Das zweite Argument gibt die Funktion an, die beim Auftreten des Ereignisses aufgerufen werden soll.

Beim Klicken auf den Link erscheint nun zuerst eine Meldungsfenster mit dem Text »click«, erst danach wird zur angeklickten Webseite navigiert.

Das Ereignisverzeichnis

Der Ereignisempfänger erhält ein Verzeichnis als Argument übergeben, das Ereignisverzeichnis. Das Ereignisverzeichnis enthält verschiedene Einträge zu dem Ereignis, wie beispielsweise »type« mit einer Zeichenfolge, welche den Typ des Ereignisses angibt.

Main.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head><meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<title>Main</title><style type="text/css">

</style></head><body>

<p><a id="a" href="http://example.invalid">example</a></p>

<pre><code><script>/*<![CDATA[*/

a = window.document.getElementById( "a" );

a.addEventListener( "click", event => window.alert( event.type ) );

/*]]>*/</script></code></pre></body></html>

Protokoll
[click]
Navigation zu http://example.invalid

Das mehrfache  Hinzufügen eines Empfängers

Es ist auch möglich, mehrfach  einen Empfänger für ein Ereignis festzulegen. Alle festgelegten Empfänger werden dann in der Reihenfolge ihres Hinzufügens aufgerufen.

Main.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head><meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<title>Main</title><style type="text/css">

</style></head><body>

<p><a id="a" href="http://example.invalid">example</a></p>

<pre><code><script>/*<![CDATA[*/

a = window.document.getElementById( "a" );

a.addEventListener( "click", event => window.alert( "A" ));

a.addEventListener( "click", event => window.alert( "B" ));

/*]]>*/</script></code></pre></body></html>

Protokoll
[A]
[B]
Navigation zu http://example.invalid

Das Sperren der Weiterleitung

Ein Ereignisempfänger kann es mit Hilfe der stopImmediatePropagation-Funktion des erhaltenen Ereignisses auch verhindern, daß weitere Empfänger aktiviert werden.

Main.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head><meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<title>Main</title><style type="text/css">

</style></head><body>

<p><a id="a" href="http://example.invalid">example</a></p>

<pre><code><script>/*<![CDATA[*/

a = window.document.getElementById( "a" );

a.addEventListener
( "click", event =>{ window.alert( "A" ); event.stopImmediatePropagation(); });

a.addEventListener( "click", event => window.alert( "B" ));

/*]]>*/</script></code></pre></body></html>

Protokoll
[A]
Navigation zu http://example.invalid

Das Aufsteigen eines Ereignisses

Wenn ein Link angeklickt wurde, der in einem Absatz enthalten ist, dann ist es nicht ganz einfach zu sagen, ob nun der Absatz oder der Link angeklickt wurde. Man könnte auch sagen, daß beide  angeklickt wurden.

Entsprechend werden zuerst die Ereignisempfänger des inneren und dann auch noch die des äußeren Elements aufgerufen.

Wenn »event.eventPhase« gleich »2« ist, so ist das Ereignis gerade beim innersten vom Ereignis betroffenen Element angelangt, ist es gleich »3« so ist das Ereignis beim Aufsteigen in umgebende Elemente.

Main.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head><meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<title>Main</title><style type="text/css">

</style></head><body>

<p id="p"><a id="a" href="http://example.invalid">example</a></p>

<pre><code><script>/*<![CDATA[*/

p = window.document.getElementById( "p" );

a = window.document.getElementById( "a" );

p.addEventListener( "click", event =>{ window.alert( event.eventPhase ); });

a.addEventListener( "click", event =>{ window.alert( event.eventPhase ); });

/*]]>*/</script></code></pre></body></html>

Protokoll
[2]
[3]
Navigation zu http://example.invalid

Das Festlegen der Phase

Die Ereignisbehandlung findet eigentlich in drei Phase statt: Bei der ersten Phase werden die Elemente, die das innerste betroffene Element enthalten, von außen nach innen  „absteigend“ benachrichtigt. Bei der zweiten Phase wird das innerste Element benachrichtig, und bei der dritten Phase werden die umgebenden Elemente dann noch einmal von innen nach außen  „aufsteigend“ benachrichtigt.

Beim Anklicken des Links, werden der Absatz und der Link in der folgenden Reihenfolge benachrichtigt:

Durch ein drittes Argument von »addEventListener« können wir festlegen, ob die angegebenen Funktion in der ersten Phase aktiviert werden soll. Wenn dieses Argument fehlt, so gilt es als falsch. Wenn das dritte Argument wahr ist, so wird eine Aktivierung der Funktion für die absteigende Phase hinzugefügt, sonst für die aufsteigende.

In dem folgenden Programm wird ein Ereignisempfänger für den Absatz und die erste Phase festgelegt, weswegen die angegebene Funktion nun vor der für den Link aktiviert wird, wenn der Link angeklickt wird.

Wenn »event.eventPhase« gleich »1« ist, so ist das Ereignis gerade beim Absteigen.

Main.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head><meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<title>Main</title><style type="text/css">

</style></head><body>

<p id="p"><a id="a" href="http://example.invalid">example</a></p>

<pre><code><script>/*<![CDATA[*/

p = window.document.getElementById( "p" );

a = window.document.getElementById( "a" );

p.addEventListener( "click", event =>{ window.alert( event.eventPhase ); }, true );

a.addEventListener( "click", event =>{ window.alert( event.eventPhase ); });

/*]]>*/</script></code></pre></body></html>

Protokoll
[1]
[2]
Navigation zu http://example.invalid

Das Sperren der Ereignisweitergabe

Durch »stopPropagation()« wird die Weiterleitung eines Ereignisses an Ereignisempfänger anderer  Elemente unterbunden (sei es beim Absteigen oder erst beim Aufsteigen). Die Ereignisempfänger desselben  Elements werden aber noch benachrichtigt (im Gegensatz zu »stopImmediatePropagation()«).

Main.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head><meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<title>Main</title><style type="text/css">

</style></head><body>

<p id="p"><a id="a" href="http://example.invalid">example</a></p>

<pre><code><script>/*<![CDATA[*/

p = window.document.getElementById( "p" );

a = window.document.getElementById( "a" );

p.addEventListener( "click", event =>{ window.alert( "P" ); event.stopPropagation(); }, true );

p.addEventListener( "click", event =>{ window.alert( "P1" ); }, true );

a.addEventListener( "click", event =>{ window.alert( "A" ); });

/*]]>*/</script></code></pre></body></html>

Protokoll
[P]
[P1]
Navigation zu http://example.invalid

Die Standardbehandlung eines Ereignisses

Für einige Ereignisse gibt es eine Standardbehandlung, beim Anklicken eines Links wird beispielsweise zu der Adresse des Links navigiert.

Das Unterbinden der Standardbehandlung

Für einige Ereignisse ist »cancelable« gleich »true«. In diesem Fall kann die Standardbehandlung mit »preventDefault()« unterbunden werden. Dies beeinträchtigt aber nicht die Weiterleitung an andere JavaScript -Ereignisempfänger.

Main.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head><meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<title>Main</title><style type="text/css">

</style></head><body>

<p><a id="a" href="http://example.invalid">example</a></p>

<pre><code><script>/*<![CDATA[*/

a = window.document.getElementById( "a" );

a.addEventListener( "click", event => { window.alert( event.cancelable ); event.preventDefault(); });

/*]]>*/</script></code></pre></body></html>

Protokoll
[click]
(keine Navigation)

Das onclick-Attribut

Mit einem onclick-Attribut eines Elements kann man eine Sequenz angeben, die beim Anklicken eines Elements ausgewertet werden soll.

Main.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head><meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<title>Main</title><style type="text/css">

</style></head><body>

<p><a href="http://example.invalid" onclick="alert( event.type ); f(); return false;">example</a></p>

<pre><code><script>/*<![CDATA[*/

f = () => window.alert( "f!" );

/*]]>*/</script></code></pre></body></html>

Protokoll
[click]
[f!]
(keine Navigation)

Es gibt verschiedene Möglichkeiten, eine Behandlung für ein Ereignis in JavaScript  festzulegen, beispielsweise die mit »addEventListener« und die mit einem on-Attribut. In diesem Kurs konzentrieren wir und hauptsächlich auf ein Möglichkeit, nämlich die mit »addEventListener«. Weil man aber beim Lesen anderer Quellen mit dem on-Attribut konfrontiert werden könnte, folgen hier einige Erläuterungen dazu:

Die Verwendung von »addEventListener« hat folgende Vorteile gegenüber der Verwendung eines on-Attributs.

(Die Definition der Funktion »f« wird oben erst gelesen nachdem »f()« schon verwendet wurde. Der Zeitpunkt des Aufrufs jener Funktion liegt aber meist nach dem Zeitpunkt zu dem die Definition gelesen wurde, so daß die Funktion zum Zeitpunkt ihres Aufrufs wahrscheinlich meist definiert ist.)

Aus der freien Wildbahn  Das Sperren des Kontextmenüs

Wir habe Webseiten beobachtet, welche das Kontextmenü, das normalerweise das Kopieren einer Adresse erlaubt, sperren. Das heißt, daß der Benutzer das Kontextmenü zu einem Link nicht mehr verwenden kann (falls er JavaScript  aktiviert hat). Auch, wenn diese Technik nicht unbedingt zur Nachahmung empfohlen wird, zeigen wir hier wie so etwas verwirklicht werden kann.

In dem untenstehenden Beispielskript geschieht folgendes:

main.html

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
<head><meta charset="UTF-8" />
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
<title>Main</title><style type="text/css">

#span { font-size: 500% }

</style></head><body>

<h1>Nicht kopierbarer Link</h1>

<p><a id="a" href="http://example.com">Link</span></p>

<pre><code><script>/*<![CDATA[*/

a = window.document.getElementById( "a" );

cm =( event )=>{ event.preventDefault(); }

a.addEventListener( "contextmenu", cm );

/*]]>*/</script></code></pre></body></html>

Der Browser übergibt der Funktion »cm« beim Eintreffen des Ereignisses ein Verzeichnis »event«, welches verschiedene Funktionen für das eingetretene Ereignis enthält.

Die Funktion »cm« ruft nun die Funktion »preventDefault« aus diesem Verzeichnis auf. Dadurch erfährt der Browser, daß er die normale Ereignisbehandlung, also die Anzeige des Kontextmenüs, unterdrücken soll.

Übungsaufgaben

Zur Erleichterung der Bearbeitung können Sie an Stelle von »document.getElementById« auch weiterhin NAOTWO  zum Elementzugriff verwenden, oder erst zum Schluß – nachdem die Aufgabe gelöst ist – NAOTWO  durch den Einsatz von »document.getElementById« ersetzen.

Zur Erleichterung der Bearbeitung können Sie an Stelle von »addEventListener« auch weiterhin on-Attribute verwenden, also beispielsweise an Stelle von »span.addEventListener( "click", () => span.innerHTML = 1 );« in einem Skript-Element »onclick="span.innerHTML=1"« als Attribut des span-Elements.

Durch NAOTWO  (“named access on the window object ”, NAOTWO, sprich “now two ”) werden die im HTML-Quelltext mit »id=« festgelegten Elementkennungen, falls möglich, in JavaScript  als globale Namen zur Verfügung gestellt. (Siehe auch: https://www.w3.org/TR/html5/browsers.html#named-access-on-the-window-object).
Unter HTML-Quelltext  versteht man Text, der in HTML geschrieben wurde – also beispielsweise »id=« enthält. – Etwa im Gegensatz zu der von einem Browser angezeigten Webseite.

Zur Erleichterung der Bearbeitung können Sie bei Übungsaufgaben in den folgenden Lektionen an Stelle von polyglottem HTML  auch weiterhin SIL verwenden. Dabei kann vor den SIL-Code ein style-Element gesetzt werden und hinter den SIL-Code ein script-Element. Die drei leeren Zeilen in dem folgenden SIL-Dokument können jeweils mit CSS -Code, HTML-Code beziehungsweise JavaScript -Code befüllt werden.

/   Übungsaufgabe

Schreiben Sie einen Taschenrechner mit drei Eingabefeldern, die untereinander angeordnet sind. Wir nennen das unterste Eingabefeld X, das mittlere Y und das oberste Z.

Die Felder sollen zunächst alle 0 enthalten.

Fügen Sie dann folgende Tasten hinzu:

/   Aus der freien Wildbahn  Ein nicht-kopierbarer Link

Wir habe Webseiten beobachtet, die eine Adresse in der Statusleiste des Browsers (unten) anzeigen, wenn man die Spitze des Mauszeigers auf einen Link positioniert. Das Kopieren dieser Adresse mit der rechten Maustaste wird aber verhindert, indem diese beim Öffnen des Kontextmenüs durch eine zwar verwendbare, aber weniger schöne Variante ersetzt wird. Diese weniger schöne Variante führt zunächst auf eine Umleitung, statt zu der ursprünglich angezeigten Webseite. Man kann die schöne Variante der Adresse aber bei solchen Webseiten auch nicht einfach kopieren, indem man JavaScript  ganz deaktiviert, denn die schöne Variante wird erst von JavaScript  in die Webseite eingesetzt.

Bauen Sie solch eine Webseite nach, indem Sie eine Seite mit einem Anker erstellen und folgende Punkte umsetzen:

Zusatzanforderung Erschweren Sie das Kopieren der Adresse aus dem JavaScript -Quelltext, indem Sie diese darin verschleiern.

Quellen *

Quellen *

developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers

Web application APIs https://html.spec.whatwg.org/multipage/webappapis.html

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram722802 stefan_ram:722802 Wertrückgabe in JavaScript Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd722802, slrprddef722802, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/wertrueckgabe_javascript