JavaScript/Tutorials/DOM/Ereignisverarbeitung
- 30min
- mittel
- Kenntnisse in
● Einstieg in HTML
● Einstieg in JavaScript
Alle bisherigen Beispiele wurden direkt mit dem Laden des Scripts ausgeführt. Dies hat aber (noch) nichts mit Interaktivität zu tun. Die Event-API ermöglicht die Überwachung und Behandlung von Ereignissen (Event-Handling). Dies können Klicks mit der Maus, Wischgesten (Swipes) auf einem Touchbildschirm, ankommende Daten aus dem Netzwerk oder Änderungen am DOM sein.
Moderne Scripte durchlaufen deshalb verschiedene Phasen:
- Das Dokument wird geladen
- JavaScript fügt Event-Handler an Elementknoten an.
- Der Anwender bedient das Dokument und das Script reagiert darauf.
Inhaltsverzeichnis
Die Event Loop
JavaScript-Programme unterliegen größtenteils der sogenannten Inversion of Control (Umkehr der Ablaufsteuerung). Das bedeutet: Die Ablaufsteuerung obliegt dem JavaScript-Host (also dem Browser, node.js oder andere Systeme, die JavaScript einbetten können), und der JavaScript-Code wird bei Bedarf aufgerufen, um die zum jeweiligen Zeitpunkt erforderlichen Aktivitäten auszuführen.
Die Ausführung des Top-Level Codes eines Scripts (also das, was nicht in einer Funktion steht) unterliegt hingegen nicht der Steuerungsumkehr. Dieser Teil wird ausgeführt, sobald das Script geladen und bereit zur Ausführung ist (was von den script-Attributen defer und async abhängt). Um mit dem Besucher Ihrer Seite interagieren zu können oder um auf die Erledigung von Aufgaben warten zu können, werden Sie in diesem Top-Level Code Funktionen bereitstellen und diese Funktionen zur Behandlung von auftretenden Ereignissen registrieren. Solche Funktionen nennt man Handler.
Diese Ereignisse können verschiedene Quellen haben. HTTP-Requests können ein Ergebnis liefern, die Besucherin hat einen Button geklickt, ein Timer ist abgelaufen, aus diesen Ereignissen resultieren Aufgaben (Tasks), die bei ihrer Erstellung in eine von mehreren Warteschlangen (Task Queue) gestellt werden.
Die Aufgabe des Browsers ist es nun, diese Task Queues der Reihe nach abzufragen, sich dort den ersten ausführbaren Task herauszuholen (manchmal ist er auch noch nicht ausführbar) und diesen zu erledigen. Teil dieser Erledigung ist es, die für ein bestimmtes Ereignis registrierten JavaScript-Funktionen aufzurufen. Das muss nicht nur eine sein, beispielsweise können für einen Button mehrere click-Handler registriert sein. Während die Handler aufgerufen werden, tut der Browser nichts anderes. Es ist deshalb wichtig, dass diese Funktionen schnell durchlaufen und nicht blockieren.
Nachdem alle Handler ausgeführt sind, folgt die Abarbeitung der sogenannten Mikrotask-Queue. Die wichtigsten Quellen für Microtasks sind Promises und die Funktion queueMicrotask. Der Sinn von Microtasks ist es vor allem, eine konsistente Abfolge der Codeausführung sicherzustellen. Stellen Sie sich Code dieser Art vor:
getdata('foo', processData);
doSomething();
processData
ist eine Callback-Funktion, die die Daten vom Server weiterverarbeiten soll (z.B. auf der Seite anzeigen. doSomething
ist eine Funktion, die irgendetwas anderes tut. Stellen Sie sich nun vor, getdata('foo') wäre noch nicht gelaufen. In diesem Fall müssten zuerst die Daten vom Server geladen werden, und wenn sie da sind, kann processData laufen. Das geschieht aber asynchron. Währenddessen kehrt getdata() zurück und doSomething wird vor processData ausgeführt. Wenn nun getdata('foo') ein zweites Mal ausgeführt wird, sind die Daten im Cache und processData könnte sofort laufen. Nun wird doSomething nach processData ausgeführt. Sie haben also keine konsistente Reihenfolge, in der Ihre Funktionen laufen, und wenn sich processData und doSomething mit dem gleichen Teil des DOM beschäftigen, kann das zu Durcheinander führen.
Wenn Sie aber den Aufruf von processData als Mikrotask vorsehen, wird processData immer nach doSomething ausgeführt.
Wenn alle Mikrotasks abgearbeitet sind, sorgt der Browser dafür, dass das HTML Dokument neu layoutet und dargestellt wird. Da diese Aktivität mit der Bildwiederholrate der Grafikkarte synchronisiert ist, ist die Ausführungsgeschwindigkeit der EventLoop an die Framerate Ihrer Grafikkarte gekoppelt, und diese Framerate ist das Limit, wieviele Ereignisse pro Sekunde verarbeitet werden können.
Event-Handling
Ein HTML-Dokument wird vom Browser geladen, geparst und bleibt dann unverändert im Browser, bis das Fenster geschlossen wird. JavaScript wird zwar ebenso geladen, bietet dann aber eine Interaktivität, mit der der Nutzer das Dokument ändern kann. Dabei werden drei Phasen unterschieden:
- Phase Eins: Das Dokument wird empfangen und geparst
Dabei wird der Top-Level Teil der vorgefundenen Scripte ausgeführt (siehe oben).- Der Top-Level Code definiert Objekte und Funktionen, die für die spätere Nutzung zur Verfügung stehen.
- Nicht alle notierten Funktionen werden dabei bereits aufgerufen.
- Je nachdem, wo und wie das Script geladen wurde, hat es zu diesem Zeitpunkt noch keinen vollständigen Zugriff auf das Dokument. ECMAScript-Module und Scripte mit dem
defer
-Attribut können das Dokument vollständig nutzen, alle anderen Scripte dürfen nur auf den Teil zugreifen, der sich oberhalb des <script>-Elements befindet.
- Phase Zwei: Das Dokument ist fertig geladen
Der vollständige Zugriff auf das Dokument über das DOM ist erst jetzt möglich. Das DOM zeigt diesen Zustand durch dasDOMContentLoaded
-Event an, auf das Sie sich in Phase Eins registrieren können.- Registrieren von Event-Handlern: Das Script greift auf das Dokument oder auf Elementknoten darin an und registriert für die Ereignisse, für die es sich interessiert, Funktionen. Diese werden aufgerufen, sobald das Ereignis vom Browser verarbeitet wird.
- Inhalt oder Darstellung bestehender Elemente können jetzt schon verändert und dem Dokument auch neue Elemente hinzugefügt werden (siehe DOM-Manipulation).
- Phase Drei: Der Anwender bedient das Dokument und das Script reagiert darauf
Wenn die überwachten Ereignisse an den entsprechenden Elementen im Dokument auftreten, werden die registrierten Handler-Funktionen ausgeführt.
traditionelles Event-Handling
Es gibt noch viele Script-Beispiele und Tutorials im Netz, in denen Event-Handler als HTML-Eventattribute direkt in das HTML-Dokument geschrieben werden.
<button onclick="alert('Hallo Welt!');">Drück mich! </button>
Diese Schreibweise mit der Vorsilbe on- wurde auch im traditionellen Event-Handling verwendet. Sie ist Englisch und steht z. B. bei onclick für bei einem Klick.
window.onload
In diesem Beispiel ist der JavaScript-Code im head des Dokuments gespeichert. Der Zugriff auf das output
-Element würde erfolgen, bevor der Absatz im DOM überhaupt vorhanden wäre.
Deshalb wird das Script mit window.onload
erst ausgeführt, wenn die Seite im Browser geladen und geparst ist.
<!DOCTYPE html>
<html lang="de">
<head>
<script>
window.onload = start;
function start() {
document.querySelector('#interaktiv').onclick = klickverarbeitung;
}
function klickverarbeitung() {
document.querySelector('output').innerText += ' Huhu, das ist von Javascript eingefügter Text.';
}
</script>
</head>
<body>
<h1>Beispiel für traditionelles Event-Handling</h1>
<button id="interaktiv">Klick mich!</button>
<output></output>
</body>
</html>
Da sich der Script-Bereich im head des Dokuments befindet, sind die mit JavaScript angesprochenen Elemente beim Parsen des Skripts noch nicht vorhanden.
Deshalb wird an das globale Window-Objekt mit der Punkt-Notation ein load-Event angehängt, das die Funktion start
aufruft.
In der Funktion start
erhält der Button, der mit querySelector über seine id interaktiv
aufgerufen wird, ein Klick-Event zugewiesen, das onclick (engl. bei einem Klick) die Funktion klickverarbeitung
aufruft. Diese weist dem output-Element, das mit querySelector ermittelt wurde, mittels innerText die Zeichenkette zu.
Diese traditionelle Methode scheint sehr einfach, hat jedoch einige Nachteile. So kann man jeweils nur ein Event an Elemente hängen - weitere überschreiben bestehende Event-Handler. Deshalb hat sich eine fortgeschrittene Ereignisvarbeitung mit addEventListener durchgesetzt.
Event-Handler registrieren: addEventListener
Heutzutage hat sich eine einfache Methode, Event-Handler dynamisch an Elemente zu hängen, durchgesetzt:
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('#interaktiv').addEventListener('click', klickverarbeitung);
function klickverarbeitung () {
document.querySelector('output').innerText += ' Huhu, das ist von Javascript eingefügter Text. \n';
}
});
Das Beispiel entspricht im HTML-Aufbau und Funktion dem ersten Beispiel.
Da sich der Script-Bereich im head des Dokuments befindet, sind die mit JavaScript angesprochenen Elemente beim Parsen des Skripts noch nicht vorhanden.
Deshalb wird an das document-Objekt mit der addEventListener-Methode ein Event-Handler angehängt, der beim Feuern des DOMContentLoaded-Events eine anonyme Funktion aufruft, die wiederum dem Button mit der id interaktiv
einen Event-Handler zuweist, der bei einem Klick die Funktion klickverarbeitung
aufruft.
Das DOMContentLoaded-Event bietet gegenüber dem load-Event einige Vorteile, da es schon beim Laden und Parsen des DOM feuert, wenn evtl. umfangreichere externe Skripte und Ressourcen wie Bilder und Videos noch geladen werden.
readyState
nicht mehr auf 'loading' steht, dürfen Sie keinen Handler für das DOMContentLoaded Event mehr registrieren, er wird nicht mehr aufgerufen.Mit diesem fortgeschrittenen Event-Handling könnten an ein Element mehrere Event-Handler angehängt werden, die unterschiedliche Aktionen etwa bei Klick, Touch oder dem Auslösen mit einem Stift auslösen.
Event-Handler entfernen: removeEventListener
Einen mit der addEventListener-Methode hinzugefügten Event-Handler können Sie mit der Schwester-Methode removeEventListener wieder entfernen. Die Methode erwartet dieselben Parameter, die addEventListener beim Registrieren bekommen hat: Einen String mit dem Ereignistyp, die zu löschende Handler-Funktion und schließlich einen optionalen Boolean-Wert für die Event-Phase.
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('#interaktiv').addEventListener('click', klickverarbeitung);
document.querySelector('#entferne').addEventListener('click', entferneKlickverarbeitung);
function klickverarbeitung () {
document.querySelector('output').innerText += ' Huhu, das ist von Javascript eingefügter Text. \n';
document.querySelector('#entferne').setAttribute('aria-hidden', false);
}
function entferneKlickverarbeitung () {
document.querySelector('#interaktiv').removeEventListener('click', klickverarbeitung);
document.querySelector('output').innerText += ' Event-Handler wurde entfernt. \n';
}
});
Das Beispiel enthält zwei Buttons, von denen nur der linke sichtbar ist. Der "Entferne!"-Button besitzt ein aria-hidden-Attribut und wird durch CSS ausgeblendet.
Innerhalb der Funktion klickverarbeitung
wird der bereits bekannte Text eingefügt. In einer weiteren Anweisung wird das ARIA-Attribut mit setAttribute auf false
gesetzt und so durch seine CSS-Festlegung sichtbar.
Durch einen Klick auf den "Entferne"-Button wird die Funktion entferneKlickverarbeitung
aufgerufen, die mit removeEventListener('click', klickverarbeitung);
die Funktionalität des linken Buttons entfernt und eine entsprechende Meldung im output-Element ausgibt.
Auf Events reagieren
Bis jetzt wurden unsere Programme immer nach dem Laden der Webseite automatisch ausgeführt. Interessant wird es jedoch erst, wenn der Anwender selbständig eingreifen kann und unser Programm reagiert.
<button id="button">Drück mich!</button>
<output></output>
document.addEventListener('DOMContentLoaded', function () {
let anzahl = 0,
text = '';
document.getElementById('button').addEventListener('click', gedrueckt);
function gedrueckt() {
anzahl = anzahl + 1;
if (anzahl < 10) {
text = 'Sie haben den Button ' + anzahl +'mal gedrückt!';
}
else if (anzahl < 15) {
text = 'Sie haben jetzt bereits ' + anzahl + 'mal geklickt.\n' +
'Wollen Sie sich nicht einen Kaffee gönnen?';
}
else {
text = 'Jetzt haben Sie schon ' + anzahl + 'mal geklickt - mir wird langweilig.';
}
document.querySelector('output').innerText = text;
}
});
Wenn das DOM aufgebaut ist, feuert DOMContentLoaded und führt die anonyme Funktion aus.
Mit der addEventListener-Methode wird eine Ereignisüberwachung an den Button gehängt.
Sobald der Button gedrückt (click) wird, wird die Funktion gedrueckt
aufgerufen. Diese erhöht den Zähler um 1 und gibt dann aus, wie oft der Button bereits angeklickt wurde.
Die Ereignisüberwachung anderer Events wie mousemove oder touchstart (dem Berühren eines Touchscreens) kann genauso eingerichtet werden.
Event-Objekt
Den Ereignisbehandlungsfunktionen wird ein Argument übergeben: das Ereignisobjekt, das zusätzliche Informationen über das Ereignis enthält. Wenn wir z. B. wissen wollen, welche Maustaste gedrückt wurde, können wir uns die Eigenschaft Event.button des Ereignisobjekts ansehen.
let text = '';
document.querySelector('#button').addEventListener('mousedown', event => {
if (event.button == 0) {
text = 'Sie haben den linken Mausbutton gedrückt!';
} else if (event.button == 1) {
text = 'Sie haben den mittleren Mausbutton gedrückt!';
} else if (event.button == 2) {
text = 'Sie haben den rechten Mausbutton gedrückt!';
}
document.querySelector('output').innerText = text;
console.log(text);
});
Propagation - Weitergabe von Ereignissen
Für die meisten Ereignistypen erhalten Event-Handler, die auf Knoten mit Kindern registriert sind, auch Ereignisse, die in den Kindern auftreten. Wenn ein Button innerhalb eines div-Elements angeklickt wird, sehen die Ereignisbehandler des divs auch das Klick-Ereignis.
Wenn jedoch sowohl das div als auch der Button einen Handler haben, erhält der spezifischere Handler - der auf dem Button - den Vorzug. Man sagt, dass sich das Ereignis nach außen ausbreitet, von dem Knoten, an dem es passiert ist, zu dem übergeordneten Knoten dieses Knotens und weiter bis zum root des Dokuments. Schließlich, nachdem alle Handler, die auf einem bestimmten Knoten registriert sind, an der Reihe waren, erhalten Handler, die auf dem gesamten Fenster registriert sind, die Chance, auf das Ereignis zu reagieren.
Zu jedem beliebigen Zeitpunkt kann ein Event-Handler die Methode stopPropagation auf dem Event-Objekt aufrufen, um zu verhindern, dass weiter oben registrierte Handler das Event erhalten. Dies kann nützlich sein, wenn Sie z. B. einen Button innerhalb eines anderen klickbaren Elements haben und Sie nicht möchten, dass Klicks auf den Button das Klickverhalten des äußeren Elements aktivieren.
let div = document.querySelector('div');
let button = document.querySelector('button');
div.addEventListener('click', () => {
event.currentTarget.classList.add('chosen');
console.log('Event-Handler für Div.');
});
button.addEventListener('click', event => {
event.currentTarget.classList.add('chosen');
console.log('Event-Handler für Button.');
if (document.getElementById('check').checked) {
event.stopPropagation();
}
});
Das Beispiel registriert click-Handler sowohl für den Button als auch für das sie umgebende div-Element. Wenn der Button geklickt wird, werden beide Handler ausgeführt. Mit Event.currentTarget wird das Element identifiziert, dessen Handler gerade ausgefüht wird. Mit classList.add erhält es über die Klasse chosen
einen farbigen Hintergrund.
In der Funktion für den Button wird überprüft, ob die Checkbox ausgewählt ist. Trifft dies zu, ruft der Handler für den Button stopPropagation auf, wodurch der Handler für das div nicht ausgeführt wird.
Information: Performance-Tipp
Mittlerweile hat es sich wohl herumgesprochen, dass Änderungen an der Darstellung nicht über das (womöglich mehrfache) Setzen der style-Eigenschaft, sondern über eine Änderung von Klassen vorgenommen wird.
Event.target - wo kommt's her?
Die meisten Ereignisobjekte haben eine target-Eigenschaft (engl. für Ziel, hier aber der Auslöser, auf den die Benutzeraktion gerichtet ist), die auf das Element verweist, von dem sie stammen. Sie können diese target-Eigenschaft verwenden, um ein weites Netz für eine bestimmte Art von Ereignis auszuwerfen.
Wenn Sie z. B. ein Formular mit vielen Eingabeelementen haben, kann es bequemer sein, einen einzigen Click-Handler auf dem äußeren Knoten zu registrieren und mit der Target-Eigenschaft herauszufinden, ob und wenn ja welcher Button angeklickt wurde, anstatt einzelne Handler auf allen Schaltflächen zu registrieren.
document.body.addEventListener('click', event => {
if (event.target.nodeName == 'BUTTON') {
console.log('geklickt: ', event.target.textContent);
document.querySelector('output').innerText += event.target.textContent;
}
});
In diesem Beispiel gibt es eine virtuelle Tastatur mit 27 Buttons, aber nur einem Event-Handler, der an den body gehängt wurde. In einer if-Abfrage wird mit Event.target ermittelt, ob der Klick von einem Button ausgelöst wurde. Falls dies zutrifft wird der textContent ausgelesen und in der Konsole, bzw. in einem langen String im output-Element ausgegeben.
Standardverhalten unterdrücken
Information: Standardverhalten
Interaktive Elemente wie Verweise, Buttons oder input-Elemente und damit verbundene label haben ein Standardverhalten (default behavior), d.h. sie sind anklickbar oder mit der Tab-Taste ( ↹ ) durchtabbbar.
Der Browser behandelt also standardmäßig gewisse Ereignisse und führt die Standardaktion (englisch default action) aus, ohne dass der Seitenautor eine entsprechende JavaScript-Logik definieren musste.
Theoretisch können Sie diese Funktionalität mit jedem Element nachbauen, praktisch machen Sie sich doppelt Arbeit, verkomplizieren das Markup und den Code und erschweren die Zugänglichkeit Ihrer Seite für Screenreader.
Die oben erwähnte Einteilung in statisches HTML und dynamisches JavaScript ist so nicht ganz richtig. Es gibt in HTML neben reinen Textauszeichnungelementen wie einer Überschrift oder einem Textabsatz auch Elemente, die bereits eine browsereigene Funktionalität haben, wie z.B. Verweise, Buttons oder input-Elemente und damit verbundene label.
Teilweise ist es jedoch nicht erwünscht, diese Standardaktionen durchzuführen und etliche Eventtypen gestatten es, die Standardaktion zu unterdrücken. Ob ein Eventtyp dies gestattet, erkennen Sie an der cancelable
Eigenschaft des Event-Objekts, die Sie mit JavaScript zur Laufzeit abfragen können und die für jeden Eventtyp in der Event-Referenz des Wikis gelistet ist.
Ein click-Event, das z. B. durch Anklicken eines Links ausgelöst wird, würde die aktuelle Seite verlassen. Handelt es sich bei der Seite um ein Formular, könnten bereits Eingaben gemacht worden sein, die damit verloren gehen. Man könnte die Benutzer nun fragen, ob das wirklich gewünscht ist.
Ein submit-Event, das z.B. durch button type="submit"
ausgelöst wird, sendet eingegebene Formulardaten ab und sorgt für einen Reload der Seite. Bei einer browsereigenen Validierung sollen richtig eingegebene Daten jedoch erhalten bleiben, sodass das submit-Event unterdrückt werden muss.
document.addEventListener('click', function(event) {
if (event.target.tagName == "A" && event.target.href) {
if (!confirm("Ihre eingegebenen Daten gehen verloren. Sind Sie sicher?"))
event.preventDefault();
}
});
click
Events unterliegen dem bubbling und werden deshalb auch am Dokument sichtbar. Die target
Eigenschaft des Event-Objekts verweist auf das angeklickte Element. Ist dies ein a Element mit einer href-Eigenschaft, und wurden Formulardaten verändert (was hier durch eine globale Variable angedeutet wird), wird in einer Bestätigungsbox abgefragt, ob der Nutzer die Seite wirklich verlassen möchte. Wenn nicht, wird der Klick durch Aufruf der preventDefault-Methode des Event-Objekts unwirksam gemacht.
Außerdem wäre zu überlegen, ob man bei leeren oder (unberührten) Eingabefeldern die Abfrage weglassen sollte.unload
wird Ihnen das auf keinen Fall gelingen, weil dieses Event nicht cancelable ist. Bei beforeunload
zeigen nur manche Browser eine Dialogbox an (z.B. Firefox), andere (z.B. Chrome) verweigern die Blockade des unload-Vorgangs durch einen Dialog, weil sich das zum „Einsperren“ eines Anwenders auf der Seite missbrauchen lässt. Bestätigungsabfragen sollten Sie daher stellen, bevor das Verlassen der Seite ausgelöst wird, also im submit
Event eines Forms oder im click
Event eines Buttons oder LinksMit preventDefault können Sie bei einem Event, das cancelable ist, die Standardaktion des Browsers unterdrücken, wie z. B. in diesem Beispiel, in dem die verlinkte Großansicht eines Bildes schon innerhalb der Webseite angezeigt wird. Der Klick auf den Link löst das JavaScript, aber kein Navigieren zu einer neuen Ressource aus.
Bubbling, Capturing und stopPropagation
Bei ineinander verschachtelten Elementen feuern Events nicht nur beim auslösenden Element, sondern auch bei dessen Elternelementen. Die Phase, in der das Event zu den Elternelementen aufsteigt, nennt man Bubbling-Phase, die Phase, in der das Event absteigt, nennt man Capturing-Phase. Die Methode addEventListener
hat noch einen dritten optionalen Parameter, useCapture
, über den gesteuert wird, in welcher Phase der Eventhandler aufgerufen wird. Mit der Eigenschaft des Eventobjekts stopPropagation()
können Bubbling bzw. Capturing verhindert werden.
Mit dieser Testseite soll das Event-Capturing und -Bubbling veranschaulicht werden. Dazu wurden mehrere Divs mit farbigem Hintergrund ineinander verschachtelt.
Für jedes dieser Divs kann ein Eventhandler für pointerup, pointerdown, keyup und keydown registriert werden. Mit useCapture true werden die Eventhandler in der Capturing-Phase ausgeführt, mit useCapture false in der Bubbling-Phase.
Die Eventhandler schreiben einen Eintrag in die Browserkonsole und lassen für eine kurze Zeit eine Textinfo erscheinen. Die Info erscheint zeitverzögert, um die Abfolge auch verfolgen zu können.
Das hellblaue Div ist absolut positioniert und verschoben.
Bitte mit Maus, Finger oder Stift in eines der farbigen Rechtecke klicken, oder die Divs mit der Tabulatortaste anwählen und dann eine Taste drücken.
// Eventhandler nach Wunsch registrieren
if(document.querySelector("#downFalse").checked) {
eventElement.addEventListener("pointerdown", handleEventUseCaptureFalse, false);
eventElement.addEventListener("keydown", handleEventUseCaptureFalse, false);
}
if(document.querySelector("#downTrue").checked) {
eventElement.addEventListener("pointerdown", handleEventUseCaptureTrue, true);
eventElement.addEventListener("keydown", handleEventUseCaptureTrue, true);
}
if(document.querySelector("#upFalse").checked) {
eventElement.addEventListener("pointerup", handleEventUseCaptureFalse, false);
eventElement.addEventListener("keyup", handleEventUseCaptureFalse, false);
}
if(document.querySelector("#upTrue").checked) {
eventElement.addEventListener("pointerup", handleEventUseCaptureTrue, true);
eventElement.addEventListener("keyup", handleEventUseCaptureTrue, true);
}
// Die Eventhandler
function handleEventUseCaptureTrue(event) {
eventHandler(this, event, true);
}
function handleEventUseCaptureFalse(event) {
eventHandler(this, event, false);
}
function eventHandler(eventElement,event,useCapture) {
// Wenn Checkbox für Stoppropagation angehakt, Event nicht weiterreichen, kein bubbling und kein capturing
if(chkStopPropagationElement.checked) event.stopPropagation();
// Auf diese Tastaturereignisse soll nicht reagiert werden
if(event.key == "Tab" || event.key == "Shift" || event.key == "Alt" || event.repeat) return;
// Die drei Eventphasen
let phase = event.eventPhase;
if(event.eventPhase == 1) phase = "Capturing-Phase";
else if(event.eventPhase == 2) phase = "Zielphase";
else if(event.eventPhase == 3) phase = "Bubbling-Phase";
// Konsolenausgabe
console.log(event.type,eventElement.id,phase,"useCapture: "+useCapture);
// Events sichtbar machen
visualizeEvents.add(eventElement,event,phase,useCapture);
}
Auf dieser Testseite werden Divs als anklickbare Elemente verwendet. Dadurch ist die Seite nicht zugänglich. Das ist aber auf einer Testseite ok.
Siehe auch
JavaScript/Tutorials
- Mouse and more (Eventverarbeitung mit Maus, Touch oder Stift)
- Debounce und Throttle (Bei einer Kette von Events Funktionen nicht zu oft aufrufen)
Das JavaScript befindet sich in einem script-Element im Head des Dokuments: