Zum Inhalt springen

Websiteentwicklung: JavaScript: DOM-Ereignisbehandlung

Aus Wikibooks


Ereignisbehandlung im DOM

[Bearbeiten]

Das DOM-Ereignis-Modell (englisch: DOM Event Model) ist eine Erweiterung des DOM-Kerns. Sie dient dazu, die Behandlung von Ereignissen zu definieren.

Voraussetzung ist die komplette Interpretation von 'DOM Core 2' für 'DOM 2 Event Model'. Ob diese Erweiterung oder dieses Merkmal interpretiert wird, kann im DOM-Kern über die Implementierungsschnittstelle abgefragt werden:
document.implementation.hasFeature('Events', '2.0')
Ist die Rückgabe true, so wird diese Erweiterung komplett interpretiert, bei false eignet sich das Darstellungsprogramm nicht für diese Erweiterung. SVG 1.1 fordert etwa die Interpretation dieser Erweiterung neben der von DOM Core 2. Für dieses Format ist demgemäß per Voraussetzung keine Abfrage notwendig, bei einem konformen Programm ist die Rückgabe immer true.


Ähnlich wie der eigentliche DOM-Kern kann diese Erweiterung ebenfalls zu diversen Zugänglichkeitsproblemen führen. Ist die Präsentation eines Dokumentes von diversen Ereignissen abhängig - unter anderem auch von Aktivitäten des Nutzers mit Zeigergeräten oder durch Fokussierung von Elementen, entfernt sich die Präsentation schnell vom eigentlichen Inhalt des Dokumentes. Zudem ist nicht bei jedem Gerät notwendig für jedes definierte Ereignis ein Gerätebestandteil vorhanden, welcher das jeweilige Ereignis hervorrufen kann. In dieser Hinsicht hat es allerdings in den letzten Jahren hinsichtlich der Behandlung von Ereignissen von Zeigergeräten wie etwa einer Maus eine breite Verallgemeinerung gegeben, so dass Autoren davon ausgehen können, dass interaktive Geräte für Zeigerereignisse auch eine Funktionalität bereithalten. Dies muß nicht zwangsläufig eine Maus sein, nur weil die Ereignisse aus historischen Gründen nach diesem Gerät benannt sind, die Funktion können auch andere Techniken bereitstellen. Etwa verfügen inzwischen Mobiltelephone und sogenannte Schreibtafel-Rechner oder Flach-Rechner (englisch: tablet-PC; tablet) über berührungsempfindliche Bildschirme. Insbesondere Rechner vom Typ 'Notebook' verfügen meist alternativ oder zusätzlich zu einer Maus über ein Tastfeld (englisch: touchpad). In beiden Fällen repräsentieren die Finger des Nutzers ein Zeigergerät. Weil allerdings die Finger nicht immer den Bildschirm oder das Tastfeld berühren, kann es dabei bei einigen Zeigerereignissen zu einem eingeschränkten Bedienkomfort kommen. Dies kann auch dadurch bedingt sein, dass anders als bei dem Zeiger einer klassischen Maus der Zielpunkt nicht so eindeutig mit einem bestimmten Punkt eines Fingers oder einem bestimmten Finger verknüpft ist, sondern vom Gerät nur grob 'über den Daumen' gepeilt ist. Filigrane Aktionen sind dadurch massiv erschwert, was allerdings auch auf viele Nutzer zutrifft, die in ihrer Feinmotorik eingeschränkt sind oder nicht an die Verwendung von Rechner-Mäusen gewöhnt sind. Von daher kann ein Autor nicht davon ausgehen, dass kleine, dicht zusammenliegende Bedienflächen gut nutzbar sind oder kompliziertere Bedienvorgänge oder Interaktionsabläufe von Nutzer immer gut umsetzbar sind. Von daher schon empfiehlt sich eine möglichst einfache, intuitive Benutzung mit großen Bedienflächen, um nicht Nutzergruppen auszuschließen. Da Geräte wie Mobiltelephone und Schreibtafel-Rechner zunehmend mehr verwendet werden, können Nutzer mit deutlich eingeschränkten feinmotorischen Möglichkeiten gar zur Mehrheit gehören.

Im Sinne der allgemeinen Zugänglichkeit und Barrierefreiheit und im Sinne des Schichtenmodells zur Trennung des Inhalts (XHTML, SVG etc) von Dekoration (CSS, anwenderseitige Skriptsprachen, DOM-Anwendungen) kann zudem nicht davon ausgegangen werden, dass der jeweilige Nutzer immer ein Gerät verwendet, welches eine interaktive Bedienung zuläßt. Insofern muß sich ein jeder Autor auch hier wieder immer wieder ins Gedächtnis rufen, dass die per Skript, DOM und Ereignis-Erweiterung hervorgerufene Manipulation der Präsentation nicht den eigentlichen Inhalt des Dokumentes ändert, sondern eben nur eine alternative Präsentation bereitstellt. Weil diese natürlich leicht die Anmutung eines veränderten Inhaltes suggerieren kann, ist die Verlockung sowohl für Autoren als auch Nutzer groß, diese transiente Manifestation für inhaltlich relevant zu halten. Sofern sich daraus für Nutzer auch nur ein subjektiver Mehrwert an Inhalt (nicht nur an Komfort und Ergonomie) ergibt, ist eine faktische Zugänglichkeitsbarriere entstanden. Es handelt sich dann faktisch nicht mehr um eine alternative Präsentation von Inhalt, sondern um eine unzugängliche transiente Manifestation mit der Anmutung neuen Inhalts. An diesem Punkt gilt es für den Autor von vorne herein zu überlegen, welche inhaltliche Information mit dem Dokument angeboten werden soll und diese dann auch als realen Inhalt zu notieren.

Je nach konkreter Anwendung gilt es dann zu überlegen, ob durch die interaktive Präsentation wirklich etwas von inhaltlicher Relevanz transportiert wird - dann ist dies auch im eigentlichen und zugänglichen Inhalt etwa als Text zu berücksichtigen. Ansonsten kann es ausreichen, die inhaltlich nicht besonders relevante interaktive Präsentation als solche zu beschreiben, wenn es sonst keinen relevanten Inhalt gibt, etwa bei einem massiv interaktiven Spiel. Erst durch die Beschreibung des Sachverhaltes bekommt der Nutzer Klarheit darüber, dass das ansonsten informationslose Dokument nicht unzugängliche Informationsanmutungen nur per interaktivem Skript verfügbar macht.

Die vom der DOM-Ereignisbehandlung definierten Ereignisse sind nicht unbedingt die einzigen verfügbaren Ereignisse. Formate können weitere Schnittstellen und Ereignisse in Erweiterungen bereitstellen, welche dann ebenfalls für das jeweilige Format verfügbar sind. (X)HTML und SVG definieren zudem auch eigene Attribute als Ereignislauscher. Dies ist ein älterer Ansatz mit ähnlicher Funktionalität und erfordert nicht generell ein DOM. Im Sinne einer strikten Trennung von Inhalt und Dekoration im Schichtenmodell sollten diese allerdings vermieden werden. Zudem kann mit diesen Attribute nur je ein Lauscher pro Ereignistyp registriert werden, diese Einschränkung fällt mit dieser DOM-Erweiterung weg.


Begriffe zur Ereignisbehandlung

[Bearbeiten]

Ereignisse im Sinne des DOM können aus verschiedenen Quellen kommen, je nach Quelle haben diese jeweils einen spezifischen Begriff. Zudem ist jeweils festgelegt, für welche Strukturen Ereignisse zutreffen und wie diese zugeordnet werden, wenn sie in einer Kaskade von verschachtelten Elementen auftreten.

  • Nutzerschnittstellenereignisse (englisch: UI events, user interface events) - diese Ereignisse werden vom Nutzer mit externen Geräten hervorgerufen, wie etwa der Maus, dem Tastfeld, berührungsempfindlicher Bildschirm, Tastatur etc.
  • Logische Nutzerschnittstellenereignisse (englisch: UI Logical events, user interface logical events) - dies sind von spezifischen Geräten unabhängige Ereignisse, etwa das Fokussieren oder Ansprechen von Elementen.
  • Mutationsereignisse (englisch: Mutation events) - diese Ereignisse treten bei einer Änderung der Dokumentstruktur auf.
  • Abfangen (englisch: capturing) - in einer Kaskade von verschachtelten Elementen kann ein Vorfahre ein Ereignis ab- oder auffangen, registriert es also vor seinen Nachfahren, wenn solch ein Abfangmodus aktiviert ist.
  • Blubbern (englisch: bubbling) - in einer Kaskade von verschachtelten Elementen kann ein Element ein Ereignis zu seinen Vorfahren hochsteigen oder (hoch-)blubbern lassen, ähnlich wie bei kochendem Wasser Gasblasen blubbern. So kann solch ein Ereignis dann auch bei den Vorfahren registriert werden.
  • Aufhebbar (englisch: cancelable) - das Darstellungsprogramm kann bei bestimmten Konstellationen von Ereignis und Element eine voreingestellte Funktion haben. Diese kann aufhebbar sein und kann dann etwa durch eine vom Autor realisierte Funktion ersetzt werden. Beispiele wären etwa der Aufruf eines Verweises per Mausklick oder das Absenden eines Formulars.

Der Fluß von Ereignissen

[Bearbeiten]

Je nachdem, wo und wie Ereignisse entstehen, fließen sie durch die Dokumentstruktur. Ein vom Nutzer ausgelöstes Ereignis, sagen wir ein Mausklick, muß über hier nicht weiter diskutierte Schnittstellen zum Darstellungsprogramm durchgereicht werden, welches dieses Ereigniszielen zuordnet. Dabei wandert das Ereignis zunächst von dem Fenster des Programmes in die Repräsentation des Dokumentes als Dokument-Objekt-Modell und dort die Verschachtelung der Knoten hinab bis zu jenem Element, bei welchem der Mausklick erfolgt ist, jedenfalls, wenn es nicht auf dem Weg dahin abgefangen wird. Bei jedem Element, bei dem das Ereignis abgefangen wird, wird es registriert. Bei dem letzten Element, dem Ereignisziel, kann das Ereignis dann ebenfalls registriert werden, auch wenn dieses nicht explizit auf Abfangen eingestellt ist. Dann setzt das Blubbern ein, das Ereignis steigt die Verschachtelung wieder hoch, sofern man dies nicht unterbindet. Bei jedem Vorfahren kann es dann ebenfalls registriert werden, wobei es dann auch jeweils wieder möglich ist, das Blubbern zu unterbinden. Wo das Ereignis bereits zuvor abgefangen und registriert wurde, wird es beim Blubbern nicht erneut registriert. Folglich kann man sich bei Vorfahren des Ereigniszieles entscheiden, ob bei diesen ein Ereignis vor dem Erreichen des Ereignisziels registriert wird oder danach. Im Bedarfsfalle kann man zudem bei jeder Registrierung eine weitere Ausbreitung des Ereignisses verhindern.

Andere, nicht von außen kommende Ereignisse können allerdings einen kürzeren Weg haben, etwa erst im Darstellungsprogramm oder im DOM beginnen. Nicht alle Ereignisse blubbern auch oder können abgefangen werden, entsprechend ergibt sich dann ein etwas anderes Verhalten.

Damit ein Ereignis bei einem Element registriert werden kann, ist bei diesem auf das Ereignis zu lauschen, dazu gibt es eine entsprechende Methode (englisch: event listener).


Schnittstelle Ereignisziel, 'EventTarget'

[Bearbeiten]

Mit der Schnittstelle können Ereignislauscher registriert und auch wieder entfernt werden. Die Schnittstelle gilt für alle Knoten. Sei K solch ein Knoten.

Methoden

[Bearbeiten]
  • K.addEventListener(Typ,Lauscher,Abfangen)

Mit der Methode wird ein Ereignislauscher beim Knoten K registriert, welches somit zum Ereignisziel wird. Werden identische Lauscher beim selben Knoten registriert, werden alle Duplikate entsorgt. Es ist im Bedarfsfalle also nur notwendig, einen Lauscher wieder abzumelden.

Typ ist eine Zeichenkette, mit welcher der Typ von Ereignis angegeben wird. Welche Typen verfügbar sind, ist nur zum Teil von der DOM-Ereignisbehandlung vorgegeben, zum anderen Teil durch formatspezifische Erweiterungen.

Lauscher ist vom Typ 'EventListener' - eine Schnittstelle oder Funktion, welche aufgerufen wird, wenn das Ereignis eintritt.

Abfangen ist true, wenn das Ereignis abgefangen werden soll, false wenn nicht.

Einen Rückgabewert gibt es nicht.


  • K.removeEventListener(Typ,Lauscher,Abfangen)

Mit der Methode wird ein Ereignislauscher beim Knoten K entfernt. Es wird nur jener Ereignislauscher entfernt, bei dem alle Parameter mit der Registrierung übereinstimmen. Wenn kein solcher Lauscher beim Knoten K registriert ist, hat die Methode keinen Effekt.

Typ ist eine Zeichenkette, mit welcher der Typ von Ereignis angegeben wird. Welche Typen verfügbar sind, ist nur zum Teil von der DOM-Ereignisbehandlung vorgegeben, zum anderen Teil durch formatspezifische Erweiterungen.

Lauscher ist vom Typ 'EventListener' - eine Schnittstelle oder Funktion, welche aufgerufen wird, wenn das Ereignis eintritt.

Abfangen ist true, wenn das Ereignis abgefangen werden soll, false wenn nicht.

Einen Rückgabewert gibt es nicht.


  • K.dispatchEvent(Ereignis)

Mit der Methode kann bei dem Knoten künstlich ein Ereignis ausgelöst werden. Ereignisziel ist der Knoten K. Der Parameter Ereignis ist vom Typ 'Event'.

Der Rückgabewert gibt an, ob eine voreingestellte Funktionalität aufgehoben wurde oder nicht. true, wenn sie aufgehoben wurde, sonst false.


Beispiele

[Bearbeiten]

Meist werden für Beispiele auch andere Schnittstellen aus der Ereignisbehandlung gebraucht, von daher gibt es dann bei diesen einen Vorgriff auf die Erklärung in späteren Abschnitten dieses Kapitels. Oft mag indes bereits die Namensgebung ausreichen, um das jeweilige Beispiel zu verstehen.

Beispiel zum Ereignislauscher und zum Ereignisfluß. Eine genauere Erklärung findet sich im Element desc des SVG-Dokumentes, welches als Beispiel dient:

<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
     xml:lang="de" viewBox="-600 -600 1200 1200"
     stroke="#0ff" stroke-width="0">
<title>Ereignislauscher und Ereignisfluß</title>
<desc>
Acht bunte Kreise sind entlang zweier nicht sichtbarer
Kreise angeordnet. 
Es gibt jeweils ein Paar in den Farben blau, rot, grün, violett.
Von einen Paar ist jeweils ein Kreis auf dem nicht sichtbaren
Kreis mit kleinerem Radius angeordnet, der andere auf dem mit
größerem Radius.
Alle haben einen cyanen Strich der Breite 0.

  
Bei Skriptinterpretation:
Für die acht Kreise sind jeweils Ereignislauscher registriert,
Beim kleineren Radius wird das Ereignis aufgefangen, beim größeren nicht.

Gleiche Farben haben jeweils ein gemeinsames Gruppenelement.

Bei blau und grün fangen die Gruppen das Ereignis nicht auf,
bei rot und violett fangen die Gruppen das Ereignis auf.
 
Bei den grünen und den violetten Kreisen wird die weitere Ausbreitung
des Ereignisses gestoppt, bei den anderen nicht.

Wird bei einem Kreis ein Ereignis registriert, wird der Strich schwarz.
Wird bei einer Gruppe ein Ereignis registriert, ändert sich die Strichbreite.

Bei jedem Klick wird mittig als Text der Fragmentidentifizierer des Elementes
ausgegeben, bei dem etwas geändert wurde - Gruppen beginnen mit g, Kreise mit c.
g0 ist Vorfahre aller Kreise g1-g4 jeweils für zwei Kreise gleicher Farbe.
Die Angaben werden für jeden Klick aneinandergehängt, bei jedem neuen Klick
von vorne.
Dafür sorgt ein Lauscher auf dem Wurzelelement, welcher bei jedem Klick den
Textknoten leert.

Um alle Gruppen herum ist eine weitere Gruppe angeordnet, 
registriert diese ein Ereignis, wird die Füllopazität geändert.
Da dieses keine Ereignisse auffängt, kommt hier nur ein Ereignis an,
wenn es zuvor nicht gestoppt wurde, also nur bei blau und rot.


Ergebnis: 
Grüne Kreise anklicken hat keinen sichtbaren Effekt außer der Anzeige der
zugehörigen Fragmentidentifizierers.
Violetten Kreis anklicken ändert die Strichbreite beider violetter Kreise und
beim angeklickten Kreis wird der Strich schwarz. Weil auch der andere Kreis
nun eine von null verschiedene Strichbreite hat, ist dieser sichtbar.

Rote oder blaue Kreise anklicken hat einen ähnlichen Effekt wie bei den violetten Kreisen.
Zusätzlich ändert sich hier noch die Füllopazität.
Durch unterschiedliches Auffangverhalten wird bei blauen und roten Kreisen
allerdings die Reihenfolge der Abarbeitung umgekehrt sein, was sich hier
bei den Angaben zu den Fragmentidentifizierern bemerkbar macht.
</desc>

 
<g id="g0"> 
 
<g id="g1"> 
<circle id="c1" cx="200" cy="0" r="100" fill="#00f" transform="rotate(0)" />  
<circle id="c2" cx="400" cy="0" r="100" fill="#00f" transform="rotate(225)" />
</g>

<g id="g2"> 
<circle id="c3" cx="200" cy="0" r="100" fill="#f00" transform="rotate(90)" /> 
<circle id="c4" cx="400" cy="0" r="100" fill="#f00" transform="rotate(315)" />
</g>

<g id="g3"> 
<circle id="c5" cx="200" cy="0" r="100" fill="#0f0" transform="rotate(180)" />  
<circle id="c6" cx="400" cy="0" r="100" fill="#0f0" transform="rotate(45)" />
</g>

<g id="g4"> 
<circle id="c7" cx="200" cy="0" r="100" fill="#a0a" transform="rotate(270)" />  
<circle id="c8" cx="400" cy="0" r="100" fill="#a0a" transform="rotate(135)" />
</g>

</g>

<text id="T" y="20" text-anchor="middle" font-size="40" font-family="sans-serif"> </text>

<defs>
<script type="application/ecmascript">
  // Lauscher für die Kreise - rot und grün fangen ab
  document.getElementById("c1").addEventListener("click", s1, true)
  document.getElementById("c2").addEventListener("click", s1, false)
  document.getElementById("c3").addEventListener("click", s1, true)
  document.getElementById("c4").addEventListener("click", s1, false)
  document.getElementById("c5").addEventListener("click", s2, true)
  document.getElementById("c6").addEventListener("click", s2, false)
  document.getElementById("c7").addEventListener("click", s2, true)
  document.getElementById("c8").addEventListener("click", s2, false)
  
  // Lauscher für Gruppen - rot und violett fangen ab
  document.getElementById("g1").addEventListener("click", sw, false)
  document.getElementById("g2").addEventListener("click", sw, true)
  document.getElementById("g3").addEventListener("click", sw, false)
  document.getElementById("g4").addEventListener("click", sw, true)
  document.getElementById("g0").addEventListener("click", f, false)
  
  // Lauscher beim Wurzelelement, um Text bei jedem Klick zu leeren
  document.documentElement.addEventListener("click", t, true)


// Textknoten leeren
function t(e) { 
  document.getElementById("T").firstChild.data=''  
}
  
// Strich setzen  
function s1(e) {
  // bei welchem Element ist das Ereignis registriert?
  var ele = e.currentTarget
  // Strich auf schwarz setzen
  ele.setAttributeNS(null,"stroke", 'black')
  var id=ele.getAttributeNS(null,"id")
  document.getElementById("T").firstChild.appendData(id)
}

// Ausbreitung des Ereignisses stoppen, Strich setzen 
function s2(e) {  
  // Ereignisausbreitung stoppen
  e.stopPropagation()
  // bei welchem Element ist das Ereignis registriert?
  var ele = e.currentTarget
  // Strich auf schwarz setzen
  ele.setAttributeNS(null,"stroke", 'black')
  var id=ele.getAttributeNS(null,"id")
  document.getElementById("T").firstChild.appendData(id)
}

// Strichbreite vorgeben
var sw=0
function sw(e) {
  // bei welchem Element ist das Ereignis registriert?
  var ele = e.currentTarget 
  // Strichbreite ändern und setzen
  sw=sw%10+1
  ele.setAttributeNS(null,"stroke-width", sw)
  var id=ele.getAttributeNS(null,"id")
  document.getElementById("T").firstChild.appendData(id) 
}

// Füllopazität vorgeben
var fo=100
function f(e) {
  // bei welchem Element ist das Ereignis registriert?
  var ele = e.currentTarget
  // Füllopazität behandeln
  fo=fo-5
  if (fo &lt;=10) {
    fo=100
  }
  var fio=fo/100
  ele.setAttributeNS(null,"fill-opacity", fio)
  var id=ele.getAttributeNS(null,"id")
  document.getElementById("T").firstChild.appendData(id)
}
</script>
</defs>
</svg>


Beispiel Ereignislauscher setzen und entfernen:

<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
     xml:lang="de" viewBox="-1000 -1000 2000 2000">
<title>Beispiel Ereignislauscher</title>
<desc>
Ohne Skriptinterpretation enthält ein großer schwarzer Kreis 
implizit alle relevante Information dieses Dokumentes.

Mit Skriptinterpretation erscheinen auf dem schwarzen Kreis 
200 weitere bunte Kreise ohne Informationsgehalt.
Dies sind in einer Gruppe angeordnet, für die ein Ereignislauscher 
registriert ist.
Auch der große hat einen Ereignislauscher registriert.
Klickt man den großen Kreis an, wird der Ereignislauscher
für die Gruppe wieder abgemeldet - mit einem weiteren Klick
wieder angemeldet und so weiter.

Ist der Ereignislauscher für die Gruppe registriert, so
bewirkt ein Klick auf einen der kleinen Kreise eine
zufällige Farbänderung desselben, zudem wird er nach
hinten gesetzt.
Der angeklickte Kreis wird als Ereignisziel identifiziert,
braucht also keinen eigenen Lauscher.
</desc>

<circle id="c" r="1000" /> 
<g id="es">

</g>

<defs>
<script type="application/ecmascript">
var es=document.getElementById("es") 
 
// Kreise anlegen:
var cr=0
var cw=0
var cx=0
var cy=0
var r=0
var red=0
var green=0
var blue=0
for (var i = 1; i &lt;= 200; i++){
  // wohin der Kreis
  cr = 900*Math.random()+10
  cw = 2*Math.PI*Math.random()
  cx=cr*Math.cos(cw)
  cy=cr*Math.sin(cw)
 
  // Radius des Kreises abhängig von der Position:
  r=Math.max(cr/10,10)      
 
  // neues Element circle erzeugen und Attribute setzen
  var circle = document.createElementNS("http://www.w3.org/2000/svg","circle")
  circle.setAttributeNS(null,"r", r)
  circle.setAttributeNS(null,"cx", cx)
  circle.setAttributeNS(null,"cy", cy) 
  red   = rand(5,255)
  green = rand(5,255)
  blue  = rand(5,255)
  circle.setAttributeNS(null,"fill","rgb("+ red +","+ green+","+blue+")")
       
  // neues Element in das g-Element 'es' setzen
  document.getElementById("es").appendChild(circle)
}

// Lauschen, ob ein kleiner Kreis angeklickt wird, dann dessen Farbe ändern
document.getElementById("es").addEventListener("click", farbe, false)
// Lauschen, ob großer schwarzer Kreis angeklickt wird, dann Lauscher für
// kleine Kreise ab- oder wieder anmelden...
document.getElementById("c").addEventListener("click", ausan, false)

// an oder aus?
var an=true
function ausan() {
  if (an) {
    an=false
    // Lauscher der Gruppe abmelden
    document.getElementById("es").removeEventListener("click", farbe, false)
  } else {
    an=true
    // Lauscher der Gruppe wieder anmelden
    document.getElementById("es").addEventListener("click", farbe, false)    
  }

}

// Farbe ändern
function farbe(e) {
  // bei welchem Element ist das Ereignis eingetreten?
  var ele = e.target
  // neue Farbe
  red   = rand(5,255)
  green = rand(5,255)
  blue  = rand(5,255)
  ele.setAttributeNS(null,"fill","rgb("+ red +","+ green+","+blue+")") 
  // Element nach unten setzen, als erstes Kind des Elternelementes, 
  // falls es das nicht schon ist
  if (ele.previousSibling) {
     ele.parentNode.insertBefore(ele,ele.parentNode.firstChild);
  }
}

// ganzzahlige Zufallszahl...
function rand (min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min
} 
</script>
</defs>
</svg>


Beispiel DOM-Ereignisbehandlung - definieren und auslösen von Ereignissen:

<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
     xml:lang="de" viewBox="-250 -150 500 300">
<title>DOM-Ereignisbehandlung - definieren und auslösen von Ereignissen</title>
<desc>
Zwei Kreise sind nebeneinander angeordnet.

Bei Skriptinterpretation:
Auf umständliche Weise wird beim Anklicken eines Kreises 
die Füllung beider Kreise zufällig geändert.
Beim angeklickten Kreis erfolgt das direkt, 
worauf ein Ereignis erzeugt wird, 
welches dies auch beim anderen auslöst.
</desc>

 
<circle id="c1" cx="-100" cy="0" r="100" fill="blue" /> 
<circle id="c2" cx="100" cy="0" r="100" fill="green" /> 


<defs>
<script type="application/ecmascript">  
  // Ereignis definieren
  var e=document.createEvent('Event')
  e.initEvent('etc',true,true)   
  // die beiden Kreise identifizieren
  var c1=document.getElementById("c1")
  var c2=document.getElementById("c2")
  // Lauscher bei den Kreisen
  // normaler Klick
  // samt Funktionsaufruf mit Parameterübergabe 
  c1.addEventListener("click", function(){mach(c1,c2)}, false)
  c2.addEventListener("click", function(){mach(c2,c1)}, false) 
  // auf eigenes Ereignis lauschen
  c1.addEventListener("etc", function(){f(c1)}, false)
  c2.addEventListener("etc", function(){f(c2)}, false) 
  
function mach(a,b) {
  // neue Farbe setzen
  f(a)
  // Ereignis beim anderen Kreis auslösen
  b.dispatchEvent(e)  
}

function f(ele) {
  // neue Farbe
  var red   = rand(5,255)
  var green = rand(5,255)
  var blue  = rand(5,255)
  ele.setAttributeNS(null,"fill","rgb("+ red +","+ green+","+blue+")")
}

// ganzzahlige Zufallszahl...
function rand (min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min
}

</script>
</defs>
</svg>


Schnittstelle Ereignislauscher, 'EventListener'

[Bearbeiten]

Dies ist die Schnittstelle, mit welcher Autoren angeben, was passieren soll, wenn ein registriertes Ereignis eintritt.

Bei ECMAScript/JavaScript ist das in der Praxis eine Funktion, die aufgerufen wird.

Sei L ein solcher Lauscher.

Methode

[Bearbeiten]
  • L.handleEvent(Ereignis)

Diese Methode wird immer dann aufgerufen, wenn ein Ereignis eintritt, mit welchem L aufgerufen wird. Der Parameter Ereignis ist vom Typ 'Event'. Das Ereignis wird als (erster) Parameter an den Lauscher weitergereicht und kann bei diesem analysiert werden. Von daher ist die Methode an sich praktisch kaum explizit anzuwenden, weil das Ereignis automatisch durchgereicht wird.


Schnittstelle Ereignis, 'Event'

[Bearbeiten]

Mit der Schnittstelle werden Informationen über ein Ereignis verfügbar gemacht. Das Ereignis wird als (erster) Parameter an den Lauscher weitergereicht und kann bei diesem analysiert werden.

Wurde zum Beispiel der Lauscher 'meinLauscher' registriert, so kann man auf das Ereignis etwa wie folgt zugreifen:

function meinLauscher(e) {
  // bei welchem Element ist das Ereignis eingetreten?
  var ele = e.target
  // etc
}

Sei im Folgenden also wie bei diesem Beispiel e ein solches Ereignis.

Attribute

[Bearbeiten]
  • e.bubbles ist nur lesbar und gibt an, ob das Ereignis e blubbert oder nicht.

Wenn das Ereignis blubbert, ist die Rückgabe true, sonst false.

  • e.cancelable ist nur lesbar und gibt an, ob die voreingestellte Funktion aufhebbar ist.

Ist die voreingestellte Funktion zu verhindern, ist die Rückgabe true, sonst false.

  • e.currentTarget ist nur lesbar und vom Typ 'EventTarget'.

Rückgabe ist also jener Knoten, bei dem der Ereignislauscher registriert ist, dies ist nicht notwendig das Ereignisziel.

  • e.eventPhase ist eine nur lesbare Zahl, die angibt, welche Ereignisphase gerade abläuft.

Der Wert 1 steht für die Abfangphase (Konstante dazu: CAPTURING_PHASE)
Der Wert 2 steht für die Zielphase, also das Ereignis ist gerade am Zielelement angekommen (Konstante dazu: AT_TARGET)
Der Wert 3 steht für die Blubberphase, also das Ereignis blubbert bereits wieder hoch (Konstante dazu: BUBBLING_PHASE)

  • e.target ist nur lesbar und vom Typ 'EventTarget'.

Rückgabe ist also das derzeitige Ereignisziel. Dies ist nicht notwendig der Knoten, bei dem der Ereignislauscher registriert ist.

  • e.type ist eine nur lesbare Zeichenkette und gibt den Namen des Ereignisses an.
  • e.timeStamp ist nur lesbar und vom Typ 'DOMTimeStamp'.

Rückgabe ist eine Zeit in Millisekunden, die seit dem Anfang einer Epoche bis zum Eintritt des Ereignisses vergangen ist. Traditionell wird 0 Uhr vom ersten Januar 1970 als Anfang der Epoche gewertet, auch Unix-Zeit genannt. Da auch andere Epochen verwendet werden könnten, sollte man sich auf den Absolutwert nicht verlassen, sondern immer Differenzen bilden, etwa mit einem ebenfalls mit diesem Attribut bestimmten Referenzwert.


Bei den Beispielen oben zu Ereignislauschern werden e.currentTarget und e.target verwendet.

Einfaches Musikinstrument

Folgendes Beispiel verwendet e.timeStamp, um den zeitlichen Ablauf von Ereignissen zu speichern und daraus eine Animation zusammenzusetzen. So entsteht eine einfache Farborgel, die sich vermutlich von Synästhesisten weiterentwickeln ließe. Hier wird SVG 1.1 verwendet, welches keine Audio-Ausgabe hat. Sinngemäß läßt sich das Beispiel bei Verwendung von SVG tiny 1.2 auch als einfache akustische Orgel verwenden, siehe das Beispiel eines einfachen Musikinstrumentes. Dieses könnte nun mit der im Beispiel umgesetzten Speichermethode kombiniert werden. Die Ergebnisanimation ist dann nur noch über eine Schnittstelle eines geeigneten Darstellungsprogrammes auszulesen und abzuspeichern. Das Beispiel ist nun extra so angelegt, dass das Spielen der Farborgel deklarativ passiert, also keine Skriptinterpretation benötigt, lediglich das Speichern und erneute Abspielen einer Sequenz benötigt hier den Skripteinsatz. Das Beispiel bietet somit eigentlich eine nicht triviale Hilfe für den Nutzer, die allerdings ohne Skript vermutlich nicht sinnvoll umsetzbar ist, aber immerhin beschreibbar. Ohne Skripteinsatz muß sich ein Spieler der Farborgel also den Zeitablauf selber merken und die Animation selbst erstellen, beziehungsweise diese gemerkte Komposition speichern, um sie wieder abspielen zu können.

<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
     xml:lang="de" viewBox="-500 -650 1000 1100"
     xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Farborgel</title>
<desc>
Mit den Knöpfen oben im Rechteck mit abgerundeten Ecken kann
man mit der Maus für die Dauer des Drückens die Farbe des
großen Kreises auf die Farbe des gedrückten Kreises setzen.


Bei Skriptinterpretation:
Die zeitliche Abfolge der Drückerei wird aufgezeichnet.
Ein Anklicken des großen Kreises wiederholt die aufgezeichnete
Sequenz. 
Mit abermaligem Drücken eines kleinen Kreises beginnt die
Aufzeichnung einer neuen Sequenz, die alte ist nicht mehr
verfügbar.
</desc>
 
<circle id="c" cx="0" cy="0" r="400" 
        stroke="black" fill="white" /> 

<rect x="-400" y="-600" width="800" height="100" rx="20" 
      stroke="black" fill="white" />
<g id="es" stroke="#008" stroke-width="10">
<circle id="c1" cx="-350" cy="-550" r="40" fill="#ff0">
  <set xlink:href="#c" attributeName="fill" to="#ff0" 
       begin="c1.mousedown" end="c1.mouseup; c1.mouseout" />
</circle>
<circle id="c2" cx="-250" cy="-550" r="40" fill="#0f0">
  <set xlink:href="#c" attributeName="fill" to="#0f0" 
       begin="c2.mousedown" end="c2.mouseup; c2.mouseout" />
</circle>
<circle id="c3" cx="-150" cy="-550" r="40" fill="#0ff">
  <set xlink:href="#c" attributeName="fill" to="#0ff" 
       begin="c3.mousedown" end="c3.mouseup; c3.mouseout" />
</circle> 
<circle id="c4" cx="-50" cy="-550" r="40" fill="#00f">
  <set xlink:href="#c" attributeName="fill" to="#00f" 
       begin="c4.mousedown" end="c4.mouseup; c4.mouseout" />
</circle>
<circle id="c5" cx="50" cy="-550" r="40" fill="#f0f">
  <set xlink:href="#c" attributeName="fill" to="#f0f" 
       begin="c5.mousedown" end="c5.mouseup; c5.mouseout" />
</circle>
<circle id="c6" cx="150" cy="-550" r="40" fill="#f00">
  <set xlink:href="#c" attributeName="fill" to="#f00" 
       begin="c6.mousedown" end="c6.mouseup; c6.mouseout" />
</circle>
<circle id="c7" cx="250" cy="-550" r="40" fill="#f80">
  <set xlink:href="#c" attributeName="fill" to="#f80" 
       begin="c7.mousedown" end="c7.mouseup; c7.mouseout" />
</circle>
<circle id="c8" cx="350" cy="-550" r="40" fill="#000">
  <set xlink:href="#c" attributeName="fill" to="#000" 
       begin="c8.mousedown" end="c8.mouseup; c8.mouseout" />
</circle>      
</g>  


<defs>
<script type="application/ecmascript">
 // Speicher vorbereiten
 var farbe= new Array()
 var anfang= new Array()
 var ende= new Array() 
 var dauer= new Array()
 var pause= new Array()
 // Index für den ersten Wert
 var index=0
   
 // Gruppe es identifizieren 
 var es=document.getElementById("es")
 // großen Kreis c identifizieren
 var c=document.getElementById("c") 
 // und auf Ereignis lauschen
 es.addEventListener("mousedown", beginn, false)
 

function beginn(e) {
 // vorsichtshalber diesen Lauscher deaktivieren
 es.removeEventListener("mousedown", beginn, false)
 // und lauschen, wann der jeweilige Kreis nicht mehr
 // gedrückt wird
 es.addEventListener("mouseup", schluss, false)
 es.addEventListener("mouseout", schluss, false)  
 // dieser wurde gedrückt
 var ele = e.target
 // Farbe ermitteln und Anfangszeit
 farbe[index]=ele.getAttributeNS(null,"fill")
 anfang[index]=e.timeStamp
}

function schluss(e) {
 // anklicken des großen Kreises freischalten
 c.addEventListener("click", finale, false)  
 // weitere Aktion bei kleinen Kreisen erlauben
 es.addEventListener("mousedown", beginn, false)
 // vorsichtshalber deaktivieren
 es.removeEventListener("mouseup", schluss, false)
 es.removeEventListener("mouseout", schluss, false)
 // dieser wurde nicht mehr gedrückt
 var ele = e.target
 // Endzeit
 ende[index]=e.timeStamp
 // Index für nächsten Wert
 index+=1 

}

function finale(e) {
 // deaktivieren, wird jetzt nicht mehr gebraucht
 c.removeEventListener("click", finale, false) 
 // Anfangswert Animation
 var values=farbe[0]
 // wie lange dauert das?
 dauer[0]=ende[0]-anfang[0]
 // pause vor dem Anfang 0
 pause[0]=0
 // Anfangswert Summe Gesamtdauer der Animation
 var dur=dauer[0]
 // Anfangswert keyTimes
 var keyTimes='0'
 // nur wenn mehrere Wert da sind weiter ...
 if (index &gt; 0) {
 
  for (var i = 1; i &lt; index; i++){
   // Wertsequenz zusammensetzen
   values+=';#fff; '+farbe[i] 
   // Dauer der Pause zum vorherigen Ereignis
   pause[i]=anfang[i]-ende[i-1]
   // Dauer des Ereignisses
   dauer[i]=ende[i]-anfang[i]
   // Summe Gesamtdauer ...
   dur+=dauer[i]+pause[i]
  }
  
  // nun noch die keyTimes richtig bestimmen;
  // weil ecmascript offenbar dezimal nicht
  // genau teilt, improvisieren.
  var dummy=0
  for (var i = 1; i &lt; index; i++){  
   dummy+=Math.round(10000*dauer[i-1]/dur)/10000
   keyTimes+=';'+dummy.toFixed(4) 
   dummy+=Math.round(10000*pause[i]/dur)/10000
   keyTimes+=';'+dummy.toFixed(4)
  } 
  // (die letzte Dauer ergibt sich automatisch...)
  // Dauer der Animation in Millisekunden...
  dur=dur+'ms'
  
  var animate=document.getElementById("a")
  if (animate==null) {
    // wenn noch nicht da, 
    // neues Element animate erzeugen und Attribute setzen
    animate = document.createElementNS("http://www.w3.org/2000/svg","animate") 
    animate.setAttributeNS(null,"id", 'a')
    animate.setAttributeNS(null,"attributeName", 'fill') 
    animate.setAttributeNS(null,"restart", 'whenNotActive')
    animate.setAttributeNS(null,"begin", 'click')
    // Animation einsetzen
    document.getElementById("c").appendChild(animate) 
  }
  animate.setAttributeNS(null,"dur", dur)  
  animate.setAttributeNS(null,"calcMode", 'discrete') 
  animate.setAttributeNS(null,"keyTimes", keyTimes) 
  animate.setAttributeNS(null,"values", values)
  
  // für die nächste Sequenz:
  index=0
 }
}
</script>
</defs>
</svg>


Methoden

[Bearbeiten]
  • e.initEvent(EreignisTyp,KannBlubbern,IstAufhebbar)

Mit der Methode kann ein Ereignis e, welches zuvor mit der Schnittstelle 'DocumentEvent' erzeugt wurde, initialisiert werden, wobei der Ereignistyp festgelegt wird, ob das Ereignis blubbert und ob es aufhebbar ist.

EreignisTyp ist eine Zeichenkette entweder für einen bereits existierenden Ereignistyp wie etwa 'click' oder auch einen neuen, selbst definierten Typ, welcher allerdings nicht mit 'DOM' beginnen darf und auch nicht mit bekannten, anderweitig definierten Ereignistypen zusammenfallen sollte. Die beiden anderen Parameter sind entweder true oder false. KannBlubbern ist true, wenn das Ereignis blubbern können soll, sonst false. IstAufhebbar ist true, wenn das Ereignis aufhebbar sein soll, sonst false.

Einen Rückgabewert gibt es nicht.

Beispiel siehe das dritte bei den Ereignislauschern.


  • e.stopPropagation()

Mit der Methode wird der weitere Fluß eines Ereignisses angehalten, es kann also bei nachfolgenden Knoten nicht mehr registriert werden. Allerdings werden noch alle Ereignisse beim aktuellen Ereignisziel registriert.

Einen Rückgabewert gibt es nicht.

Beispiel siehe das erste bei den Ereignislauschern.


  • e.preventDefault()

Erfolgt normalerweise beim Eintritt des Ereignisses e eine voreingestellte Aktion, etwa der Aufruf des referenzierten Dokumentes beim Anklicken eines Verweises, und ist diese Aktion aufhebbar, so signalisiert diese Methode, dass die voreingestellte Aktion aufzuheben ist, also nicht durchgeführt wird. Ist die Aktion nicht aufhebbar, bleibt die Methode wirkungslos.

Einen Rückgabewert gibt es nicht.


Beispiel:

<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
     xml:lang="de" viewBox="-300 -300 600 600"
     xmlns:xlink="http://www.w3.org/1999/xlink">
<title>DOM-Ereignisbehandlung - voreingestellte Aktion unterbinden</title>
<desc>
Durch Anklicken eines Kreises wird ein Verweis 
zu wikimedia commons, zu den deutschen wikibooks 
oder wikipedia ausgeführt:
https://commons.wikimedia.org/
https://de.wikibooks.org/
https://de.wikipedia.org/

Bei Skriptinterpretation:
Für das Klickereignis wird die voreingestellte Aktion unterbunden und stattdessen der 
angeklickte Kreis bunt gemacht.
</desc>

<g id="es">
<a xlink:href="https://commons.wikimedia.org/">
<circle cx="0" cy="0" r="120" />
</a>
<a xlink:href="https://de.wikibooks.org/"> 
<circle cx="200" cy="0" r="80" /> 
<circle cx="0" cy="200" r="80" /> 
<circle cx="-200" cy="0" r="80" /> 
<circle cx="0" cy="-200" r="80" /> 
</a>
<a xlink:href="https://de.wikipedia.org/">
<circle cx="200" cy="-200" r="70" /> 
<circle cx="-200" cy="200" r="70" />
<circle cx="-200" cy="-200" r="70" /> 
<circle cx="200" cy="200" r="70" />  
</a>
</g>

<defs>
<script type="application/ecmascript">
 // Gruppe es identifizieren 
 var es=document.getElementById("es")
 // und auf Klick lauschen
 es.addEventListener("click", mach, false) 

function mach(e) {
  e.preventDefault()
  var ele = e.target
  var red   = rand(5,255)
  var green = rand(5,255)
  var blue  = rand(5,255)
  ele.setAttributeNS(null,"fill","rgb("+ red +","+ green+","+blue+")")   
}

// ganzzahlige Zufallszahl...
function rand (min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min
} 
</script>
</defs>
</svg>


Schnittstelle Dokument-Ereignis, 'DocumentEvent'

[Bearbeiten]

Diese Schnittstelle wird formal wie eine Schnittstelle vom Typ 'Document' angesprochen. Das vordefinierte Objekt 'document' ist also ein solches Objekt (wie im weiteren als Beispiel verwendet). Die Schnittstelle dient dazu, Ereignisse zu erzeugen, die vom Darstellungsprogramm interpretiert werden können, aber weder in der DOM-Ereignisbehandlung noch in DOM-Erweiterungen definiert werden. Da Ereignisse allerdings auch vom Autor per dispatchEvent() ausgelöst werden kann, kann zumindest auf diesem Wege natürlich jedes neu erzeugte Ereignis auch interpretiert werden.

Methode

[Bearbeiten]
  • document.createEvent(EreignisTyp)

Mit der Schnittstelle wird ein Objekt vom Typ 'Event' erzeugt, was dann auch der Rückgabewert ist. EreignisTyp ist die Bezeichnung des Ereignistyps, also eine Zeichenkette. Damit das Ereignis mit dispatchEvent() ausgelöst werden kann, ist es zunächst mit initEvent(), beziehungsweise initUIEvent() zu initialisieren.

EreignisTyp kann etwa eine Schnittstelle für bestimmte Ereignisse bezeichnen, etwa entsprechend der Namen der Ereignisschnittstellen, wie in folgenden Abschnitten beschrieben mit angehängtem s: 'UIEvents', 'MouseEvents', 'MutationEvents' oder einer entsprechenden Zeichenkette, die in einer Erweiterung definiert sind, etwa 'HTMLEvents'.

Beispiel siehe das dritte bei den Ereignislauschern.

Ereignistypen

[Bearbeiten]

Welche Ereignisse definiert sind, kann in verschiedenen Schnittstellen festgelegt sein. Auch in DOM-Erweiterungen für spezifische Formate kann es weitere Definitionen von Ereignistypen geben. Die DOM-Ereignisbehandlung definiert auch selbst einige Schnittstellen für Ereignistypen.

Neben den Ereignistypen selbst können diese Schnittstellen auch wieder Attribute und Methoden definieren, die dann jeweils auf ein zutreffendes Ereignis vom Typ 'Event' anwendbar sind, welches in den folgenden Abschnitten mit e abgekürzt wird.

Tastaturereignisse können bei einigen Darstellungsprogrammen bereits verfügbar sein, sind aber im 'DOM 2 Event Model' nicht definiert, von einer Nutzung ist also abzuraten, zumal es in dieser Hinsicht Sicherheitsbedenken gibt, Skripte könnten mit der Methode etwa die Eingabe von Kennwörtern ausspionieren, auch weil nicht eindeutig geklärt ist, ob und wie man etwa bei eingebetteten Dokumenten sicherstellen kann, dass nur das jeweils betroffene Dokument ein Tastaturereignis registriert und nicht auch alle anderen. Da einige Leute Werbung und anderen externe Inhalte einbetten, bleibt so ungewiß, ob eingetippte Informationen nicht auch über unerwünschte Wege abfließen und etwa nicht nur im vertrauenswürdig angesehenen Formular landen, welches gegebenenfalls wirklich sicher verschlüsselt per HTTPS versendet werden mag, was dann aber trotzdem nicht sicher ist, wenn die eingetippte Information über eingebettete Dokumente per Skript abgezweigt werden kann.

In letzter Konsequenz heißt dies, dass Nutzer vertrauliche Informationen per Tastatur allenfalls eingeben dürfen, wenn sie zum einen die Interpretation von anwenderseitigen Skripten deaktiviert haben, wenn keine anderen Dokumente eingebettet sind und die Eingabe beim Versenden etwa per HTTPs angemessen verschlüsselt wird. Für Autoren und Nutzer heißt dies, dass Seiten mit vertraulicher Texteingabe, die eine Skriptinterpretation vom Nutzer fordern, automatisch als unseriös und unsicher einzustufen sind. Autoren müssen solch kritische Seiten so minimalistisch gestalten, dass der jeweilige Nutzer einfach beurteilen kann, dass der Vertraulichkeit der Information Rechnung getragen wird.


Schnittstelle Nutzerschnittstellenereignis, 'UIEvent'

[Bearbeiten]

Mit der Schnittstelle werden Informationen über Nutzerschnittstellenereignisse verfügbar gemacht.

Ob diese Schnittstelle interpretiert wird, kann im DOM-Kern über die Implementierungsschnittstelle abgefragt werden:
document.implementation.hasFeature('UIEvents', '2.0')

Attribut

[Bearbeiten]
  • e.detail ist eine nur lesbare Zahl.

Die Bedeutung der Zahl hängt vom Ereignis ab und vermittelt Details über die Art des Ereignisses.

Methode

[Bearbeiten]
  • e.initUIEvent(EreignisTyp,KannBlubbern,IstAufhebbar,Ansicht,Detail)

Mit der Methode kann ein Ereignis e, welches zuvor mit der Schnittstelle 'DocumentEvent' erzeugt wurde, initialisiert werden, wobei der Ereignistyp festgelegt wird, ob das Ereignis blubbert und ob es aufhebbar ist. Zudem kann die Ansicht festgelegt werden und eine Zahl für eine Detailinformation angegeben werden.

EreignisTyp ist eine Zeichenkette entweder für einen bereits existierenden Ereignistyp wie etwa 'click' oder auch einen neuen, selbst definierten Typ, welcher allerdings nicht mit 'DOM' beginnen darf und auch nicht mit bekannten, anderweitig definierten Ereignistypen zusammenfallen sollte. Die beiden anderen Parameter sind entweder true oder false. KannBlubbern ist true, wenn das Ereignis blubbern können soll, sonst false. IstAufhebbar ist true, wenn das Ereignis aufhebbar sein soll, sonst false. Ansicht ist vom Typ 'views::AbstractView', wird also in einem anderen DOM-Modul namens DOM-Views festgelegt, sofern da nicht besonderes notwendig ist, kann null angegeben werden. Detail ist eine ganze Zahl, eine Detailinformation über das Ereignis repräsentierend.

Einen Rückgabewert gibt es nicht.

Für den EreignisTyp definiert die DOM-Ereignisbehandlung drei Typen:

DOMFocusIn

[Bearbeiten]

Dies Ereignis tritt ein, wenn das Ereignisziel den Fokus bekommt. Dies kann mit einem Zeigergerät erfolgen, aber auch etwa über die Tastatur. Man beachte, dass das für (X)HTML spezifische Ereignis focus, welches eine ähnliche Bedeutung hat, nur für Formularelemente relevant ist, DOMFocusIn ist hingegen für alle fokussierbaren Elemente relevant, die also etwa über ein Zeigergerät oder die Tastatur oder eine andere Eingabemethode erreichbar sind. In SVG sind etwa alle graphischen Elemente fokussierbar.

Das Ereignis blubbert, ist nicht aufhebbar und hat keine Detailinformationen.

DOMFocusOut

[Bearbeiten]

Dies Ereignis tritt ein, wenn das Ereignisziel den Fokus verliert. Ansonsten siehe auch sinngemäß DOMFocusIn.

Das Ereignis blubbert, ist nicht aufhebbar und hat keine Detailinformationen.

DOMActivate

[Bearbeiten]

Dies Ereignis tritt ein, wenn das Ereignisziel aktiviert wird. Dabei ist es unerheblich, ob es per Zeigergerät, per Tastatur oder anderweitig aktiviert wird. Von daher eignet sich dieses Ereignis eigentlich gut, um einen geräteunspezifischen, barrierefreien Zugang zu ermöglichen. In der Praxis wurde das Ereignis allerdings in vielen Darstellungsprogrammen nicht implementiert oder nicht korrekt implementiert, was dann wieder Zugänglichkeitsprobleme nach sich zieht, die schwer vom Autor vorherzusagen sind, ohne Details über Fehler und Mängel von einzelnen Versionen von Darstellungsprogrammen zu kennen.

In der Praxis wurde eher so vorgegangen, dass das Maus-Ereignis 'click' diese Funktion weitgehend übernimmt, weil dieses Ereignis inzwischen praktisch mit allen Eingabegeräten erreichbar ist, die über irgendeine graphische und interaktive Präsentation von Inhalten verfügen, was jetzt nicht bedeutet, dass 'click' notwendig einen Zugang über die Tastatur oder exotischere Methoden für speziellere Behinderungen ermöglichen würde, die für DOMActivate gerade vorgesehen sind.

Hier zeichnet sich einmal wieder ab, wie Fehler und Mängel in Darstellungsprogrammen einen barrierefreien Zugang zu Informationen erschweren, selbst wenn Autoren per Spezifikation zugängliche und barrierearme Methoden einsetzen.

Das Ereignis blubbert, ist aufhebbar und hat Detailinformationen:
1 für eine einfache Eingabe, etwa per Klick oder Eingabetaste
2 für eine 'besondere Eingabe', etwa ein Doppelklick oder eine Tastenkombination von Eingabetaste und Hochstelltaste.

Beispiel Nutzerschnittstellenereignis

[Bearbeiten]
<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
     xml:lang="de" viewBox="0 0 600 400"
     font-size="40" font-family="sans-serif">
<title>UIEvents 2.0 per Skript</title>
<desc>
Testbeispiel mit Kreis und Text 
und als fremdem Objekt ein XHTML-Formular.
Das Formular sollte sich absenden lassen,
Ziel ist allerdings dasselbe Dokument.
Zwei get-Parameter sollten beim Absenden an
die URI angehängt werden.

  
Bei Skriptinterpretation:
Wird ein SVG-Element aktiviert, so ändert es seine Füllung.
Bekommt es den Fokus, wird der Strich rot.
Verliert es den Fokus, wird der Strich blau.

Bei den XHTML-Formular-Elementen kommt Text
hinzu, bei Aktivierung 'A', Fokussierung 'F',
bei Fokus weg 'D'.
</desc>


<g id="es">
<circle id="c" cx="120" cy="120" r="100" /> 
<text id="t1" x="240" y="50">Text 1</text>
<text id="t2" x="240" y="100">Text 2</text>
<text id="t3" x="240" y="130" font-size="20"> </text>
<foreignObject x="240" y="160" width="300" height="220">
 <form xmlns="http://www.w3.org/1999/xhtml" action=''>
   <fieldset>
     <input name="eingabe" type="text" size="20" value="Text 3 " /><br />
     <input name="submit" type="submit" value="Senden " />
   </fieldset>
 </form> 
</foreignObject>  
</g>

<defs>
<script type="application/ecmascript">
 var im=document.implementation.hasFeature('UIEvents', '2.0') 
 if (im) {
  document.getElementById("t3").firstChild.data='UIEvents 2.0 implementiert'
 } else {
  document.getElementById("t3").firstChild.data='UIEvents 2.0 nicht implementiert'
 }
  
 // Gruppe es identifizieren 
 var es=document.getElementById("es")
 // und auf Ereignis lauschen
 es.addEventListener("DOMActivate", DA, false) 
 es.addEventListener("DOMFocusIn", DFi, false)  
 es.addEventListener("DOMFocusOut", DFo, false) 
 
function DA(e) {
  var ele = e.target
  var wer = ele.tagName
  if (wer!='input') {
    var red   = rand(5,255)
    var green = rand(5,255)
    var blue  = rand(5,255)
    ele.setAttributeNS(null,"fill","rgb("+ red +","+ green+","+blue+")") 
  } else {
    var val=ele.getAttributeNS(null,"value")   
    val=val+'A'
    ele.setAttributeNS(null,"value",val) 
  }
}

function DFi(e) {
  var ele = e.target
  var wer = ele.tagName
  if (wer!='input') {
    ele.setAttributeNS(null,"stroke","red") 
  } else {
    var val=ele.getAttributeNS(null,"value")   
    val=val+'F'
    ele.setAttributeNS(null,"value",val)
  } 
}

function DFo(e) {
  var ele = e.target
  var wer = ele.tagName
  if (wer!='input') {
    ele.setAttributeNS(null,"stroke","blue") 
  } else {
    var val=ele.getAttributeNS(null,"value")   
    val=val+'D'
    ele.setAttributeNS(null,"value",val)
  }
}

// ganzzahlige Zufallszahl...
function rand (min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min
}  
</script>
</defs>
</svg>

Schnittstelle Mausereignis, 'MouseEvent'

[Bearbeiten]

Diese Schnittstelle ermöglicht den Zugriff auf Zeigerereignisse.

Ob diese Schnittstelle interpretiert wird, kann im DOM-Kern über die Implementierungsschnittstelle abgefragt werden:
document.implementation.hasFeature('MouseEvents', '2.0')

Attribute

[Bearbeiten]

Alle Attribute sind nur lesbar.

  • e.detail ist eine Zahl.

Das Attribut ist von UIEvent geerbt, die Zahl hat aber eine spezifische Bedeutung:
Die Zahl gibt hier an, wie oft ein Mausknopf gedrückt wurde, also drücken und loslassen, wobei die Lokalisierung der Maus die gleiche bleibt. Bei einer Bewegung der Maus zwischen drücken und loslassen wird der Wert auf 0 zurückgesetzt.

  • e.altKey ist true, wenn während des Ereignisses gleichzeitig die Taste 'Alt' gedrückt wurde, sonst false.
  • e.ctrlKey ist true, wenn während des Ereignisses gleichzeitig die Steuerungstaste/Kontrolltaste gedrückt wurde, sonst false.

Diese Taste ist im englischsprachigen Raum oft mit 'Ctrl' beschriftet, im deutschsprachigen Raum eher mit 'Strg'.

  • e.metaKey ist true, wenn während des Ereignisses gleichzeitig die Metataste gedrückt wurde, sonst false.

Auf vielen Tastaturen ist diese Taste nicht verfügbar, bei einigen steht darauf nicht 'Meta' sondern ein auf der Spitze stehendes Quadrat. Sofern keine Metataste verfügbar ist, wird häufig eine andere für diese Funktion akzeptiert. Heute findet man häufig eine Taste mit einem komplizierteren Symbol drauf, welches einem vereinfachten microsoft-windows-Logo ähnelt. Diese Taste wird häufig als Ersatz für die Metataste verwendet, was aber insbesondere bei Verwendung eines Betriebssystems von microsoft zu Konflikten führen kann, wenn dieses das Tastaturereignis anderweitig verwendet. Generell kann man also nicht davon ausgehen, dass solch eine Taste beim Nutzer verfügbar ist. Von einer Verwendung ist also eher abzuraten.

  • e.shiftKey ist true, wenn während des Ereignisses gleichzeitig die Umschalttaste gedrückt wurde, sonst false.

Die Umschalttaste findet sich meist doppelt am linken und rechten Rand der Tastatur und hat einen nicht ausgefüllten Pfeil nach oben drauf, daher manchmal auch Hochstelltaste genannt.

  • e.button ist eine Zahl, die angibt, welcher Mausknopf gedrückt wird.

Für rechtshändige Mäuse: 0 für links, 1 für die Mitte, 2 für rechts.
. Für linkshändige Mäuse: 2 für links, 1 für die Mitte, 0 für rechts.

Für die Praxis ist zu beachten, dass viele Darstellungsprogramme 1 und 2 anderweitig belegt haben, entweder wird solch ein Ereignis dann vom Darstellungsprogramm abgefangen, bevor es im DOM ankommt oder die Aktion des Darstellungsprogrammes findet zusammen mit dem Ereignis im DOM statt. So oder so sind damit 1 und 2 für Nutzer nicht immer zugänglich oder sinnvoll nutzbar, weswegen Autoren diese Werte aufgrund dieser Fehler, Mängel oder Einschränkungen bei Darstellungsprogrammen besser nicht verwenden sollten.

  • e.clientX und e.clientY sind ganze Zahlen.

Die Attribute geben die X-, beziehungsweise Y-Position im Darstellungsbereich an, an welcher sich die Maus befand, als das Ereignis stattfand. Gegebenenfalls, insbesondere bei SVG sind diese Koordinaten also noch in ein lokales Koordinatensystem umzurechnen, um etwa ein Objekt an der Position des Ereignisses zu positionieren, oder um allgemeiner zu bestimmen, auf welchen Bereich eines Elementes, etwa eines Bildes, der Nutzer geklickt haben mag.

  • e.screenX und e.screenY sind ganze Zahlen.

Die Attribute geben die X-, beziehungsweise Y-Position auf dem Bildschirm an, an welcher sich die Maus befindet, als das Ereignis stattfindet. Eine direkte Korrelation mit dem aktuellen Dokument ist also nicht gegeben.

  • e.relatedTarget ist vom Typ 'EventTarget'.

Das Attribut erlaubt den Zugriff auf ein zeitlich korreliertes Ereignisziel. Dieses Attribut wird beim Ereignis 'mouseover' verwendet, um anzugeben, welches Ereignisziel verlassen wurde. Beim Ereignis 'mouseout' wird es verwendet, um anzugeben, über welchem Ereignisziel sich die Maus nun befindet. Bei anderen Ereignissen hat dieses Attribut aktuell keine definierte Bedeutung.

Methode

[Bearbeiten]
  • e.initMouseEvent(EreignisTyp,KannBlubbern,IstAufhebbar,Ansicht,Detail,SX,SY,CX,CY,TC,TA,TS,TM,Knopf,K)

Mit der Methode kann ein Ereignis e, welches zuvor mit der Schnittstelle 'DocumentEvent' erzeugt wurde, initialisiert werden, wobei der Ereignistyp festgelegt wird, ob das Ereignis blubbert und ob es aufhebbar ist. Zudem kann die Ansicht festgelegt werden und eine Zahl für eine Detailinformation angegeben werden.

EreignisTyp ist eine Zeichenkette entweder für einen bereits existierenden Ereignistyp wie etwa 'click' oder auch einen neuen, selbst definierten Typ, welcher allerdings nicht mit 'DOM' beginnen darf und auch nicht mit bekannten, anderweitig definierten Ereignistypen zusammenfallen sollte. Die beiden anderen Parameter sind entweder true oder false. KannBlubbern ist true, wenn das Ereignis blubbern können soll, sonst false. IstAufhebbar ist true, wenn das Ereignis aufhebbar sein soll, sonst false. Ansicht ist vom Typ 'views::AbstractView', wird also in einem anderen DOM-Modul namens DOM-Views festgelegt. Detail ist eine ganze Zahl, eine Detailinformation über das Ereignis repräsentierend, entsprechend e.detail.

Ferner gibt es den Attributen entsprechenden Parameter:
SX und SY entsprechend e.screenX und e.screenY.
CX und CY entsprechend e.clientX und e.clientY.
TC,TA,TS,TM entsprechend e.ctrlKey, e.altKey, e.shiftKey, e.metaKey.
Knopf entsprechend e.button. K entsprechend e.relatedTarget.

Einen Rückgabewert gibt es nicht.

Für den EreignisTyp definiert die DOM-Ereignisbehandlung folgende Typen:

click

[Bearbeiten]

Dies Ereignis tritt ein, wenn das Ereignisziel angeklickt wird. Ein solches Ereignis findet zum einen an der gleichen Zeigerposition statt und besteht aus der Abfolge folgender Ereignisse: mousedown, mouseup. Wie bereits beschrieben, kann e.detail herausgefunden werden, wie oft geklickt wurde und mit e.button, welcher Knopf gedrückt wurde.

Das Ereignis blubbert und ist aufhebbar. Folgende Attribute bilden den Kontext: e.screenX, e.screenY, e.clientX, e.clientY, e.altKey, e.ctrlKey, e.shiftKey, e.metaKey, e.button, e.detail

mousedown

[Bearbeiten]

Dies Ereignis tritt ein, wenn über dem Ereignisziel ein Mausknopf heruntergedrückt wird. Das Ereignis blubbert und ist aufhebbar. Folgende Attribute bilden den Kontext: e.screenX, e.screenY, e.clientX, e.clientY, e.altKey, e.ctrlKey, e.shiftKey, e.metaKey, e.button, e.detail

mouseup

[Bearbeiten]

Dies Ereignis tritt ein, wenn über dem Ereignisziel ein Mausknopf losgelassen wird. Das Ereignis blubbert und ist aufhebbar. Folgende Attribute bilden den Kontext: e.screenX, e.screenY, e.clientX, e.clientY, e.altKey, e.ctrlKey, e.shiftKey, e.metaKey, e.button, e.detail

mouseover

[Bearbeiten]

Dies Ereignis tritt ein, wenn die Maus auf das Ereignisziel gezogen wird, die Maus also von außerhalb nach darüber wechselt. Dies ist etwas anderes, als wenn sich das Ereignisziel unter die Mausposition bewegt. Das Ereignis blubbert und ist aufhebbar. Folgende Attribute bilden den Kontext: e.screenX, e.screenY, e.clientX, e.clientY, e.altKey, e.ctrlKey, e.shiftKey, e.metaKey, e.relatedTarget

mousemove

[Bearbeiten]

Dies Ereignis tritt ein, wenn die Maus über dem Ereignisziel bewegt wird. Dies ist etwas anderes, als wenn sich das Ereignisziel unter der Mausposition bewegt.

Das Ereignis blubbert und ist nicht aufhebbar. Folgende Attribute bilden den Kontext: e.screenX, e.screenY, e.clientX, e.clientY, e.altKey, e.ctrlKey, e.shiftKey, e.metaKey

mouseout

[Bearbeiten]

Dies Ereignis tritt ein, wenn die Maus vom Ereignisziel wegbewegt wird, die Maus wechselt also von drarüber nach außerhalb. Dies ist etwas anderes, als wenn sich das Ereignisziel unter der Mausposition wegbewegt. Das Ereignis blubbert und ist aufhebbar. Folgende Attribute bilden den Kontext: e.screenX, e.screenY, e.clientX, e.clientY, e.altKey, e.ctrlKey, e.shiftKey, e.metaKey, e.relatedTarget

Beispiele Mausereignisse

[Bearbeiten]

Werden die Ereignisse korrekt interpretiert?

<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
     xml:lang="de" viewBox="-1005 -1005 2010 2010">
<title>Beispiel Mausereignis</title>
<desc>
Acht Kreise bewegen sich in einem Quadrat mit abgerundeten Ecken
von Rand zu Rand und mit unterschiedliche Geschwindigkeiten in
x- und y-Richtung.


Mit Skriptinterpretation:
Die Implementierung von Mausereignissen kann getestet werden.
Die bewegten Kreise können Ziel eines Mausereignisses sein.
mouseover bewirkt einen roten Strich.
mouseout bewirkt einen blauen Strich.
mousemove bewirkt eine zufällige Änderung der Füllfarbe.
mousedown bewirkt einen hellgelben Strich.
mouseup bewirkt einen hellgrünen Strich.
click bewirkt eine Änderung der Opazität der Füllung für die
Gruppe alle Kreise.

Bei der Beurteilung der Qualität oder Korrektheit einer
Implementierung ist es relevant darauf zu achten,
daß es einen Unterschied macht, ob der Nutzer die Maus
bewegt oder sich nur ein Kreis bewegt. 
Letzteres löst kein Mausereignis aus.
Bei click ist zudem zu beachten, daß sich die Maus
während der Sequenz von mousedown und mouseup
nicht bewegen darf und beides über dem Ziel passieren
muß. Bewegt sich also zwischendurch die Maus,
findet kein Ereignis click statt.
Bewegt sich das Zielobjekt schnell genug relativ zur
Ereignissequenz, ist es ebenfalls möglich, daß
mousedown und mouseup nicht mehr dem selben Ziel
zugeordnet sind, auch dann gibt es kein Ereignis
click.

Problematisch ist mouseout, wenn zuvor mouseover zutraf,
sich dann aber das Ziel unter der Maus wegbewegt.
Dies führt eindeutig nicht zu mouseout.
Viele Darstellungsereignisse melden allerdings dieses
Ereignis, sobald die Maus wieder bewegt wird.
</desc>

<rect x="-1005" y="-1005" width="2010" height="2010" rx="100" stroke="block" />

<g id="es" fill-opacity="1"> 
<circle cx="0" cy="0" r="100" fill="#aaf" stroke-width="10">
  <animate attributeName="cx" dur="67s"
    values="-900;900;-900;900;-900" repeatDur="indefinite" />
  <animate attributeName="cy" dur="61s"
    values="0;900;0;-900;0" repeatDur="indefinite" />
</circle>

<circle cx="0" cy="0" r="100" fill="#aaf" stroke-width="10">
  <animate attributeName="cx" dur="59s"
    values="0;900;0;-900;0" repeatDur="indefinite" />
  <animate attributeName="cy" dur="60s"
    values="-900;900;-900;900;-900" repeatDur="indefinite" />
</circle>

<circle cx="0" cy="0" r="100" fill="#aaf" stroke-width="10">
  <animate attributeName="cx" dur="51s"
    values="0;-900;0;900;0" repeatDur="indefinite" />
  <animate attributeName="cy" dur="71s"
    values="900;-900;900;-900;900" repeatDur="indefinite" />
</circle>

<circle cx="0" cy="0" r="100" fill="#aaf" stroke-width="10">
  <animate attributeName="cx" dur="53s"
    values="900;-900;900;-900;900" repeatDur="indefinite" />
  <animate attributeName="cy" dur="73s"
    values="0;900;0;-900;0" repeatDur="indefinite" />
</circle>

<circle cx="0" cy="0" r="100" fill="#aaf" stroke-width="10">
  <animate attributeName="cx" dur="69.2s"
    values="0;-900;0;900;0" repeatDur="indefinite" />
  <animate attributeName="cy" dur="68.1s"
    values="0;900;0;-900;0" repeatDur="indefinite" />  
</circle>

<circle cx="0" cy="0" r="100" fill="#aaf" stroke-width="10">
  <animate attributeName="cx" dur="52.7s"
    values="0;900;0;-900;0" repeatDur="indefinite" />
  <animate attributeName="cy" dur="51.9s"
    values="0;-900;0;900;0" repeatDur="indefinite" />  
</circle>

<circle cx="0" cy="0" r="100" fill="#aaf" stroke-width="10">
  <animate attributeName="cx" dur="70.7s"
    values="0;900;0;-900;0" repeatDur="indefinite" />
  <animate attributeName="cy" dur="68.9s"
    values="0;900;0;-900;0" repeatDur="indefinite" />  
</circle>

<circle cx="0" cy="0" r="100" fill="#aaf" stroke-width="10">
  <animate attributeName="cx" dur="75.4s"
    values="0;-900;0;900;0" repeatDur="indefinite" />
  <animate attributeName="cy" dur="77.7s"
    values="0;-900;0;900;0" repeatDur="indefinite" />  
</circle>
</g>

<defs>
<script type="application/ecmascript">
document.getElementById("es").addEventListener("mouseover", over, false)
document.getElementById("es").addEventListener("mouseout", out, false)
document.getElementById("es").addEventListener("mousemove", move, false)
document.getElementById("es").addEventListener("mousedown", down, false)
document.getElementById("es").addEventListener("mouseup", up, false)
document.getElementById("es").addEventListener("click", klick, false)

function over(e) {
  e.target.setAttributeNS(null,"stroke","red")  
}
function out(e) {
  e.target.setAttributeNS(null,"stroke","blue")  
}
function move(e) {
  var red   = rand(0,255)
  var green = rand(0,255)
  var blue  = rand(0,255)
  e.target.setAttributeNS(null,"fill","rgb("+ red +","+ green+","+blue+")") 
}

function down(e) {
  e.target.setAttributeNS(null,"stroke","#ffd")  
}

function up(e) {
  e.target.setAttributeNS(null,"stroke","#afa")  
}

function klick(e) {
  var ele = e.currentTarget
  var fo=parseFloat(ele.getAttributeNS(null,"fill-opacity"))
  fo-=0.2
  if (fo &lt; 0.1) {
    fo=1
  }
  ele.setAttributeNS(null,"fill-opacity",fo)  
}


// ganzzahlige Zufallszahl...
function rand (min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min
} 
</script>
</defs>
</svg>

Beispiel Einblendung von Zusatzinformationen zum Mausereignis:

<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
     xml:lang="de" viewBox="0 0 1000 1000"
     font-size="40" font-family="sans-serif">
<title>Attribute von Mausereignissen</title>
<desc>
Ein blauer Kreis wird um einen Punkt außerhalb des
Kreises gedreht.

Bei Skriptinterpretation werden beim Anklicken des Kreises
verfügbare Informationen über das Ereignis angezeigt -
welche von den Sondertasten zusätzlich gedrückt wurde,
welcher Mausknopf und wie oft und wo gedrückt wurde.

Zudem läßt sich durch den bewegten Kreis testen, 
ob das Klickereignis korrekt interpretiert wird,
also als mousedown, mouseup komplett über dem
Ereignisziel ohne Bewegung der Maus dazwischen.
</desc>
 
<g transform="translate(650,650)">
<circle id="c" cx="200" cy="0" r="100" 
fill="#ccf" stroke="blue">
<animateTransform attributeName="transform" type="rotate" 
  values="0;360" repeatDur="indefinite" dur="20s" />
</circle>
</g>

<text id="t1" x="50" y="100"> </text> 
<text id="t2" x="50" y="150"> </text> 
<text id="t3" x="50" y="200"> </text> 
<text id="t4" x="50" y="250"> </text> 
<text id="t5" x="50" y="300"> </text> 

<defs>
<script type="application/ecmascript">
document.getElementById("c").addEventListener("click", klick, false)
document.documentElement.addEventListener("mousedown", sauber, true)

function klick(e) {
  var ele = e.target
  // welche Tasten sind gleichzeitig gedrückt worden?
  var taste='Welche Tasten? '
  if (e.altKey) {
    taste+='Alt '
  }
  if (e.ctrlKey) {
    taste+='Steuerung '
  }
  if (e.metaKey) {
    taste+='Meta '
  }
  if (e.shiftKey) {
    taste+='Umschalt '
  }
  document.getElementById("t1").firstChild.data=taste 
  // welcher Mausknopf?
  document.getElementById("t2").firstChild.data='Mausknopf: '+e.button
  // wie oft gedrückt?  
  document.getElementById("t3").firstChild.data='Wie oft? '+e.detail
  /* Wo im Darstellungsbereich? 
  (muß bei SVG meist noch in lokale Koordinaten umgerechnet werden,
   um damit was anfangen zu können, SVG hat dafür geeignete Erweiterungen.)
  */ 
  var wo='Wo Darstellungsbereich? '+e.clientX+','+e.clientY
  document.getElementById("t4").firstChild.data=wo
  // Wo auf dem Bildschirm? (brauch man das wirklich?)
  var wo='Wo Bildschirm? '+e.screenX+','+e.screenY
  document.getElementById("t5").firstChild.data=wo 
}

function sauber() {
  document.getElementById("t1").firstChild.data=' '
  document.getElementById("t2").firstChild.data=' '
  document.getElementById("t3").firstChild.data=' '
  document.getElementById("t4").firstChild.data=' '
  document.getElementById("t5").firstChild.data=' '
}
</script>
</defs>
</svg>

Beispiel zum korrelierten Ereignisziel bei mouseover und mouseout (den gleichen Effekt kann man hier allerdings auch erreichen, ohne das korrelierte Ereignisziel auszuwerten)

<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" 
     xml:lang="de" viewBox="-600 -600 1200 1200">
<title>Mausereignis - aktuelles und vorheriges Ziel</title>
<desc>
Bunte eckige Pfade bilden eine Figur ohne inhaltliche Bedeutung.

Bei Skriptinterpretation:
Wenn mit der Maus über die Formen gefahren wird, ändern sich
Strichfarbe und -dicke und die Zeichenreihenfolge.
Dies wird mit den Mausereignissen mouseover und mouseout
erreicht, zu denen zudem ausgewertet wird, welches das
zeitlich korrelierte Ereignisziel ist.
</desc>

<g id="es">
<rect x="-600" y="-600" width="1200" height="1200" fill="#a0a" />

<g stroke-opacity="0.8">
<path d="M-100-100H100V100H-100z" fill="#0ff" />
<path d="M-200,-500H200V-200H100V-100H-200Z" fill="red" />
<path d="M100,-200H500V200H200V100H100Z" fill="green" />
<path d="M200,100V500H-200V200H-100V100Z" fill="blue" />
<path d="M-500,-200H-200V-100H-100V200H-500Z" fill="yellow" />
</g>
</g>


<defs>
<script type="application/ecmascript">
document.getElementById("es").addEventListener("mouseover", over, false)
document.getElementById("es").addEventListener("mouseout", out, false)

function over(e) {
  var ele = e.target
  var rel = e.relatedTarget
  // aktueller Pfad dicker Strich
  ele.setAttributeNS(null,"stroke-width","20")
  // aktuellen Pfad nach oben setzen
  if (ele.tagName=='path') {
    ele.parentNode.appendChild(ele)
  }
  if (rel !=null) {
    if (rel.tagName=='path') {
      // alter Pfad Strich dünner
      rel.setAttributeNS(null,"stroke-width","10")
      // alten Pfad nach unten setzen
      if (ele.previousSibling) {
        rel.parentNode.insertBefore(rel,rel.parentNode.firstChild)
      }
    }
  }
}

function out(e) {
  var ele = e.target
  var rel = e.relatedTarget
  // verlassenes Element zufällige Strichfarbe
  var red   = rand(0,200)
  var green = rand(0,200)
  var blue  = rand(0,200)
  ele.setAttributeNS(null,"stroke","rgb("+ red +","+ green+","+blue+")") 
  if (ele.tagName='rect') {
    // Strich dünner
    ele.setAttributeNS(null,"stroke-width","10")  
  }
  // jetziger Pfad weißer Strich
  if (rel !=null) {
    if (rel.tagName=='path') {
      rel.setAttributeNS(null,"stroke","white")
    }
  }
}

// ganzzahlige Zufallszahl...
function rand (min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min
}
</script>
</defs>
</svg>

Schnittstelle Mutationsereignis, 'MutationEvent'

[Bearbeiten]

Diese Schnittstelle ermöglicht den Zugriff auf Mutationsereignisse.

Ob diese Schnittstelle interpretiert wird, kann im DOM-Kern über die Implementierungsschnittstelle abgefragt werden:
document.implementation.hasFeature('MutationEvents', '2.0')

Attribute

[Bearbeiten]

Alle Attribute sind nur lesbar.

  • e.attrChange gibt beim Ereignis DOMAttrModified die Art der Änderung an.

Rückgabe ist eine Zahl:
1 - Konstante 'MODIFICATION', das Attribut wurde verändert
2 - Konstante 'ADDITION', das Attribut wurde hinzugefügt
3 - Konstante 'REMOVAL', das Attribut wurde entfernt


  • e.attrName ist eine Zeichenkette mit dem Namen des Attributes, bei welchem das Ereignis DOMAttrModified eingetreten ist.
  • e.newValue ist eine Zeichenkette mit dem neuen Wert des Attributes, bei welchem das Ereignis DOMAttrModified eingetreten ist.
  • e.prevValue ist eine Zeichenkette mit dem vorherigen Wert des Attributes, bei welchem das Ereignis DOMAttrModified eingetreten ist.
  • e.relatedNode ist ein Knoten, welcher Bezug zum Mutationsereignis hat.

Wird ein Knoten geändert, so handelt es sich bei der Rückgabe um den Elternknoten. Wenn das Ereignis nur anzeigt, dass sich irgendwo in der Unterstruktur eines Knotens etwas geändert hat, so ist die Rückgabe der Knoten, bei dem die Änderung stattgefunden hat. Im Falle eines Ereignisses DOMAttrModified handelt es sich um den geänderten Attributknoten.


Methode

[Bearbeiten]
  • e.initMutationEvent(EreignisTyp,KannBlubbern,IstAufhebbar,K,V,N,Name,W)

Mit der Methode kann ein Ereignis e, welches zuvor mit der Schnittstelle 'DocumentEvent' erzeugt wurde, initialisiert werden, wobei der Ereignistyp festgelegt wird, ob das Ereignis blubbert und ob es aufhebbar ist. Zudem kann die Ansicht festgelegt werden und eine Zahl für eine Detailinformation angegeben werden.

EreignisTyp ist eine Zeichenkette entweder für einen bereits existierenden Ereignistyp wie etwa 'click' oder auch einen neuen, selbst definierten Typ, welcher allerdings nicht mit 'DOM' beginnen darf und auch nicht mit bekannten, anderweitig definierten Ereignistypen zusammenfallen sollte. Die beiden anderen Parameter sind entweder true oder false. KannBlubbern ist true, wenn das Ereignis blubbern können soll, sonst false. IstAufhebbar ist true, wenn das Ereignis aufhebbar sein soll, sonst false. Ansicht ist vom Typ 'views::AbstractView', wird also in einem anderen DOM-Modul namens DOM-Views festgelegt. Detail ist eine ganze Zahl, eine Detailinformation über das Ereignis repräsentierend, entsprechend e.detail.

K entspricht dem Attribut e.relatedNode. V entspricht dem Attribut e.prevValue (kann auch null sein). N entspricht dem Attribut e.newValue (kann auch null sein). Name entspricht dem Attribut e.attrName (kann auch null sein). W entspricht dem Attribut e.attrChange.

Einen Rückgabewert gibt es nicht.

Für den EreignisTyp definiert die DOM-Ereignisbehandlung folgende Typen:

DOMSubtreeModified

[Bearbeiten]

Das relativ unspezifische Ereignis tritt ein, wenn im DOM etwas geändert wurde. Ereignisziel ist jener Dokumentknoten, innerhalb dessen alle Änderungen stattgefunden haben, wobei auf keines seiner Kindelemente dieses zutrifft.

Das Ereignis blubbert und ist nicht aufhebbar. Ein Kontext wird nicht ausgegeben.


DOMNodeInserted

[Bearbeiten]

Das Ereignis tritt ein, wenn ein Knoten als Kind eines anderen Knotens ins Dokument eingesetzt wird. Der eingesetzte Knoten ist das Ereignisziel. Das Ereignis findet statt, nachdem der Knoten eingesetzt wird.

Das Ereignis blubbert und ist nicht aufhebbar. Ein Kontext wird mit e.relatedNode gegeben, dies enthält den Elternknoten des Ereigniszieles.


DOMNodeRemoved

[Bearbeiten]

Das Ereignis tritt ein, wenn ein Knoten als Kindknoten eines Elternknotens entfernt wird. Das Ereignis findet statt, bevor der Knoten entfernt wird. Der zu entfernende Knoten ist das Ereignisziel.

Das Ereignis blubbert und ist nicht aufhebbar. Ein Kontext wird mit e.relatedNode gegeben, dies enthält den Elternknoten des Ereigniszieles.

DOMNodeRemovedFromDocument

[Bearbeiten]

Das Ereignis tritt ein, wenn ein Knoten vom Dokument komplett entfernt wird, gegebenenfalls auch als Teil einer Teil-Dokumentbaumes. Das Ereignis findet statt, bevor der Knoten entfernt wird. Falls der Knoten direkt selbst entfernt wird, findet vorher zudem das Ereignis DOMNodeRemoved statt. Der zu entfernende Knoten ist das Ereignisziel.

Das Ereignis blubbert nicht und ist nicht aufhebbar. Ein Kontext wird nicht ausgegeben.

DOMNodeInsertedIntoDocument

[Bearbeiten]

Das Ereignis tritt ein, wenn ein Knoten neu in ein Dokument eingesetzt wird, gegebenenfalls auch als Teil einer Teil-Dokumentbaumes. Das Ereignis findet statt, nachdem der Knoten eingesetzt wird. Falls der Knoten direkt selbst eingesetzt wird, findet vorher zudem das Ereignis DOMNodeInserted statt. Der zu neue Knoten ist das Ereignisziel.

Das Ereignis blubbert nicht und ist nicht aufhebbar. Ein Kontext wird nicht ausgegeben.

DOMAttrModified

[Bearbeiten]

Das Ereignis tritt ein, nachdem ein Attributknoten geändert wurde. Ereignisziel ist der Knoten, dessen Attributknoten geändert wurde.

Das Ereignis blubbert und ist nicht aufhebbar. Ein Kontext wird gegeben mit e.attrName, e.attrChange, e.prevValue, e.newValue, e.relatedNode


DOMCharacterDataModified

[Bearbeiten]

Das Ereignis tritt ein, nachdem Text in einem Knoten geändert, eingesetzt oder entfernt wird ohne den Knoten selbst einzusetzen oder zu entfernen. Ereignisziel ist der Text-Knoten.

Das Ereignis blubbert und ist nicht aufhebbar. Ein Kontext wird gegeben mit e.prevValue, e.newValue


Das HTML-Ereignis-Modul

[Bearbeiten]

Dies Modul hat nicht direkt etwas mit der allgemeinen DOM-Ereignisbehandlung zu tun. Aus historischen Gründen definieren die Empfehlungen für HTML 4 oder XHTML 1.x nicht selbst die Ereignisse, die spezifisch für (X)HTML verwendbar sind. In dem Sinne ist dieses Modul eine (X)HTML-spezifische Erweiterung der DOM-Ereignisbehandlung, ähnlich wie SVG eine DOM-Erweiterung hat, die auch nur interpretierbar ist, falls das Format verwendet wird, nicht für andere Formate. HTML-Erweiterungen gelten also nicht für sonstige Inhalte, die kein XHTML sind oder die Interpretation der HTML-Erweiterung nicht explizit verlangen. Entsprechend ist auch die SVG-Erweiterung nur für SVG gedacht und für kein anderes Format, sofern dieses das nicht explizit fordert.

Ob einmal abgesehen von diesen Einschränkungen diese Schnittstelle interpretiert wird, kann im DOM-Kern über die Implementierungsschnittstelle abgefragt werden:
document.implementation.hasFeature('HTMLEvents', '2.0')

Das Modul verwendet dieselbe Schnittstelle, die bereits als 'Event' für die DOM-Ereignisbehandlung beschrieben wurde.

Folgende Ereignisse sind in diesem Modul definiert, ein Kontext ist bei keinen gegeben:


Das Ereignis tritt ein, wenn der Inhalt eines Dokumentes komplett geladen ist. Werden andere Dokumente in das Dokument eingebettet (etwa per frameset oder object), so werden diese auch erst komplett geladen, bevor das Ereignis eintritt.

Das Ereignis blubbert nicht und ist nicht aufhebbar.

Hilfreich ist dies Ereignis insbesondere, wenn das Skript im Quelltext vor dem damit behandelten Inhalt steht, was meist vorkommt, wenn man das Skript innerhalb von head notiert. Zumeist wird man dann abwarten wollen, dass das Dokument komplett geladen ist, bevor das Skript ausgeführt wird. Dazu wird einfach ein entsprechender Lauscher gesetzt, der auf eine Funktion verweist, die dann erst ausgeführt wird, nachdem das Ereignis eingetreten ist.


unload

[Bearbeiten]

Das Ereignis tritt ein, wenn das Dokument vom zugehörigen Fenster oder frameset entfernt wird. Anwendbar ist das Attribut nur für die Elemente body und frameset.

Das Ereignis blubbert nicht und ist nicht aufhebbar.


abort

[Bearbeiten]

Das Ereignis tritt ein, wenn das Laden eines Bildes unterbrochen wurde und ist anwendbar auf das Element object.

Das Ereignis blubbert und ist nicht aufhebbar.


error

[Bearbeiten]

Das Ereignis tritt ein, wenn ein Bild nicht korrekt geladen wurde und ist anwendbar auf object, body und frameset.

Das Ereignis blubbert und ist nicht aufhebbar.


select

[Bearbeiten]

Das Ereignis tritt ein, wenn Text in einem Textbereich ausgewählt wird und ist anwendbar auf input und textarea.

Das Ereignis blubbert und ist nicht aufhebbar.


change

[Bearbeiten]

Das Ereignis tritt ein, wenn ein Kontrollelement den Fokus verliert, nachdem sein Wert geändert wurde. Anwendbar ist das Ereignis auf select, input und textarea.

Das Ereignis blubbert und ist nicht aufhebbar.


submit

[Bearbeiten]

Das Ereignis tritt ein, wenn ein Formular abgeschickt wird und ist anwendbar auf das Element form.

Das Ereignis blubbert und ist aufhebbar.


reset

[Bearbeiten]

Das Ereignis tritt ein, wenn ein Formular zurückgesetzt wird und ist anwendbar auf das Element form.

Das Ereignis blubbert und ist nicht aufhebbar.


focus

[Bearbeiten]

Das Ereignis tritt ein, wenn ein Formularelement den Fokus bekommt. Anwendbar ist das Ereignis auf label, button, select, input und textarea.

Das Ereignis blubbert nicht und ist nicht aufhebbar.


Das Ereignis tritt ein, wenn ein Formularelement den Fokus verliert. Anwendbar ist das Ereignis auf label, button, select, input und textarea.

Das Ereignis blubbert nicht und ist nicht aufhebbar.


resize

[Bearbeiten]

Das Ereignis tritt ein, wenn die Größe des Darstellungsbereiches für das Dokument verändert wird.

Das Ereignis blubbert und ist nicht aufhebbar.


scroll

[Bearbeiten]

Das Ereignis tritt ein, wenn die Darstellung des Dokumentes gerollt wird.

Das Ereignis blubbert und ist nicht aufhebbar.


SVG-Ereignisse

[Bearbeiten]

Neben den ebenfalls nutzbaren DOM-Ereignissen definiert SVG einige eigene Ereignisse. Diese sind im wikibook zu SVG erläutert: Ereignisliste