1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
---
title: Tastaturgesteuerte JavaScript-Komponenten
slug: Web/Accessibility/Keyboard-navigable_JavaScript_widgets
translation_of: Web/Accessibility/Keyboard-navigable_JavaScript_widgets
original_slug: Web/Barrierefreiheit/Tastaturgesteuerte_JavaScript_Komponenten
---
<p>Tastaturgesteuerte JavaScript-Komponenten</p>
<h3 id="Übersicht">Übersicht</h3>
<p>Bei der Erstellung von Desktopkomponenten für Web-Applikationen, wie z.B. Menüs, Baumansichten, Richtext-Felder und Tab-Panels kommt in der Regel JavaScript zum Einsatz. Die Komponenten bestehen üblicherweise aus {{ HTMLElement("div") }}- und {{ HTMLElement("span") }}-Elementen, die von Haus aus nicht die gleiche Funktionalität wie echte Desktopkomponenten besitzen. Dieses Dokument beschreibt Techniken, die eingesetzt werden können, um JavaScript-Komponenten über die Tastatur zugänglich zu machen.</p>
<h3 id="Benutzung_von_tabindex"><span style="color: rgb(0, 0, 0);"><span class="toctext">Benutzung von tabindex</span></span></h3>
<p>Das tabindex-Attribut wurde zu Beginn als Teil von HTML 4 eingeführt, um Entwicklern zu ermöglichen, die Reihenfolge für die Fokussierung von Elementen festzulegen, die vom Benutzer mit der Tastatur angesteuert werden. Das genaue Verhalten von tabindex wurde später etwas abgeändert. Diese Änderungen sind in der HTML 5-Spezifikation beschrieben. Alle bekannten Browser implementieren fortan das neue Design.</p>
<p>Die folgende Tabelle beschreibt das Verhalten von <code>tabindex</code> in modernen Browsern:</p>
<table class="fullwidth-table" style="width: 75% !important;">
<tbody>
<tr>
<th><code>tabindex</code>-Attribut</th>
<th>Fokussierbar mit der Maus oder JavaScript über <code>element.focus()</code></th>
<th>Tab-navigierbar</th>
</tr>
<tr>
<td>Nicht vorhanden</td>
<td>Folgt der Festlegung für das Element für die Plattform ("Ja" bei Formularsteuerungen, Links, etc.).</td>
<td>Folgt der Festlegung für das Element für die Plattform.</td>
</tr>
<tr>
<td>Negativ (z.B. <code>tabindex="-1"</code>)</td>
<td>Ja</td>
<td>Nein; Entwickler muss auf Tasteneingaben reagieren und das Element über <code><a class="external text" href="../../../../En/DOM/Element.focus" rel="nofollow" title="https://developer.mozilla.org/En/DOM/Element.focus">focus()</a></code> fokussieren.</td>
</tr>
<tr>
<td>Null (z.B. <code>tabindex="0"</code>)</td>
<td>Ja</td>
<td>In der Tab-Ordnung relativ zur Position des Elements im Dokument.</td>
</tr>
<tr>
<td>Positiv (z.B. <code>tabindex="33"</code>)</td>
<td>Ja</td>
<td>Wert von <code>tabindex</code> bestimmt die Position des Elements in der Tab-Ordnung: Im Allgemeinen werden Elemente vor solchen positioniert, bei denen <code>tabindex="0"</code> gesetzt ist oder die von Natur aus per Tab steuerbar sind; Elemente mit kleinere Werten werden vor solchen mit größeren Werten positioniert (ein Element mit <code>tabindex="7"</code> wird z.B. vor <code>tabindex="11" </code>positioniert)</td>
</tr>
</tbody>
</table>
<h4 id="Einfache_Steuerungen"><span style="color: rgb(0, 0, 0);"><span class="toctext">Einfache Steuerungen</span></span></h4>
<p>Damit z.B. eine einfache Tab-Komponente über die Tastatur bedient werden kann, wird dem entsprechenden {{ HTMLElement("div") }}- oder {{ HTMLElement("span") }}-Element das tabindex-Attribut hinzugefügt. Beim folgenden Beispiel wird diese Technik für eine Checkbox angewendet, die auf einem span-Element basiert.</p>
<p><em>Beispiel 1: Eine einfache Checkbox-Komponente mit einem Bild, welche um das tabindex="0" erweitert wurde und so auch über die Tastatur gesteuert werden kann.</em></p>
<pre class="brush: html"><code><!-- Ohne die tabindex-Attribute könnten die <span>-Elemente nicht mit der Tastatur fokussiert werden -->
<div>
<span role="checkbox" aria-checked="true" tabindex="0">
<img src="checked.gif" role="presentation" alt="" />
Include decorative fruit basket
</span>
</div>
<div>
<span role="checkbox" aria-checked="true" tabindex="0">
<img src="checked.gif" role="presentation" alt="" />
Include singing telegram
</span>
</div>
<div>
<span role="checkbox" aria-checked="false" tabindex="0">
<img src="unchecked.gif" role="presentation" alt="" />
Require payment before delivery
</span>
</div></code>
</pre>
<h4 id="Gruppieren_von_Steuerungselementen"><span style="color: rgb(0, 0, 0);"><span class="toctext">Gruppieren von Steuerungselementen</span></span></h4>
<p>Für die Gruppierung von Komponenten, wie z.B. Menüs, Tableisten, Grids oder Baumansichten, sollte das Elternelement in die Tab-Ordnung aufgenommen werden (<code>tabindex="0"</code>). Außerdem sollte jede(s) untergeordnete Auswahl/Tab/Zelle/Reihe aus der Tabordnung entfernt werden (<code>tabindex="-1"</code>). Die untergeordneten Elemente sollten vom Benutzer über die Pfeiltasten angesteuert werden können (Eine ausführliche Beschreibung der Tastaturunterstützung, die im Allgemeinen für bestimmte Komponenten erwartet wird, finden Sie im <a class="external text" href="http://access.aol.com/dhtml-style-guide-working-group/" rel="nofollow">DHTML Style Guide</a>).</p>
<p>Beim nächsten Beispiel wird diese Technik bei einer Menüsteuerung eingesetzt. Sobald der Fokus der Tastatur das <ul>-Element erreicht, muss der JavaScript-Entwickler den Fokus programmatisch steuern und auf das Drücken der Pfeiltasten reagieren. Techniken für die Steuerung des Fokus innerhalb von Komponenten, sind im Abschnitt "Steuerung des Fokus innerhalb von Gruppen" weiter unten beschrieben.</p>
<p><em>Beispiel 2: Eine Menüsteuerung bei der mit tabindex die Tastaturnavigation gesteuert wird</em>.</p>
<pre class="brush: html"><code><ul id="mb1" tabindex="0">
<li id="mb1_menu1" tabindex="-1"> Font
<ul id="fontMenu" title="Font" tabindex="-1">
<li id="sans-serif" tabindex="-1">Sans-serif</li>
<li id="serif" tabindex="-1">Serif</li>
<li id="monospace" tabindex="-1">Monospace</li>
<li id="fantasy" tabindex="-1">Fantasy</li>
</ul>
</li>
<li id="mb1_menu2" tabindex="-1"> Style
<ul id="styleMenu" title="Style" tabindex="-1">
<li id="italic" tabindex="-1">Italics</li>
<li id="bold" tabindex="-1">Bold</li>
<li id="underline" tabindex="-1">Underlined</li>
</ul>
</li>
<li id="mb1_menu3" tabindex="-1"> Justification
<ul id="justificationMenu" title="Justication" tabindex="-1">
<li id="left" tabindex="-1">Left</li>
<li id="center" tabindex="-1">Centered</li>
<li id="right" tabindex="-1">Right</li>
<li id="justify" tabindex="-1">Justify</li>
</ul>
</li>
</ul></code></pre>
<h4 id="Deaktivierte_Steuerungen"><span class="toctext">Deaktivierte Steuerungen</span></h4>
<p>Wenn Sie ein Steuerelement deaktivieren, sollte dieses aus der Tab-Ordnung entfernt werden, indem <code>tabindex="-1"</code> gesetzt wird. Elemente, die Teil einer Komponentengruppe (wie z.B. Menüpunkte in einem Menü) sind, sollten über die Tastatur ansprechbar bleiben.</p>
<h3 id="Steuerung_des_Fokus_innerhalb_von_Gruppen"><span style="color: rgb(0, 0, 0);"><span class="toctext">Steuerung des Fokus innerhalb von Gruppen</span></span></h3>
<p>Wenn ein Benutzer den Fokus per Tab von einem Element wegbewegt, sollte der Fokus zu dem Element, das zuvor fokussiert war - z.B. einer Baumkomponente oder Gridzelle - zurückkehren. Es existieren zwei verschiedene Techniken, um dies zu bewirken:</p>
<ol>
<li>Verschiebung von <code>tabindex</code>: Programmatische Bewegung des Fokus</li>
<li><code>aria-activedescendent</code>: Verwaltung eines "virtuellen" Fokus</li>
</ol>
<h4 id="Technik_1_Verschiebung_von_tabindex">Technik 1: Verschiebung von tabindex</h4>
<p>Setzt man tabindex für das fokussierte Element auf "0", wird das ausgewählte Element innerhalb der Gruppe erneut fokussiert, wenn der Benutzer den Fokus per Tab fortbewegt und dann zu diesem Element zurückkehrt. Beachten Sie, dass bei der Aktualisierung von tabindex auf 0 für des zuvor selektierte Element <code>tabindex="-1"</code> gesetzt werden muss. Diese Technik wird auch verwendet, wenn auf Tastendrücke reagiert und der Fokus programmatisch weiterbewegt wird. Der tabindex wird dann entspechend aktualisiert, um das aktuell fokussierte Element anzuzeigen. Dies lässt sich wie folgt umsetzen:</p>
<p>Jeweils ein keydown-Hander wird mit einem Element der Gruppe verknüpft. Wenn der Benutzer eine Pfeiltaste drückt, um ein anderes Element anzusteuern, passiert Folgendes:</p>
<ol>
<li>Das neue Element wird codegesteuert fokussiert.</li>
<li>Der <code>tabindex</code> des fokussierten Elements wird auf "0" gesetzt.</li>
<li>Der <code>tabindex</code> des zuvor fokussierte Elements wird auf "-1" gesetzt.</li>
</ol>
<h5 id="Tipps">Tipps</h5>
<h6 id="Mit_element.focus()_den_Fokus_setzen">Mit element.focus() den Fokus setzen</h6>
<p>Benutzen Sie nicht die Funktionen <code>createEvent()</code>, <code>initEvent()</code> und <code>dispatchEvent()</code> um ein Element zu fokussieren. DOM-Focus-Events arbeiten nur informell: Sie werden vom System erzeugt, wenn ein Element fokussiert wird, aber nicht verwendet, um den Fokus zu setzen. Greifen Sie stattdessen auf <code>element.focus()</code> zurück.</p>
<h6 id="Mit_onfocus_den_Fokus_überprüfen">Mit onfocus den Fokus überprüfen</h6>
<p>Gehen Sie nicht davon aus, dass Fokusänderungen allein über die Tastatur oder Maus initiiert werden: Assistierende Technologien, wie z.B. Screenreader, sind in der Lage den Fokus für jedes fokussierbare Element zu setzen. Benutzen Sie daher <code>onfocus</code> und <code>onblur</code> um Fokusänderungen zu verfolgen.</p>
<p><code>onfocus</code> und <code>onblur</code> können nun mit jedem beliebigen Element verwendet werden. Es existiert jedoch kein Standard-DOM-Interface, um den aktuellen Fokus im Dokument abzufragen. Wenn man den Fokus verfolgen möchte, muss der aktuelle Zustand in einer JavaScript-Variablen hinterlegt werden.</p>
<h4 id="Technik_2_aria-activedescendant">Technik 2: aria-activedescendant</h4>
<p>Bei dieser Technik wird ein einzelner Event-Handler mit der Container-Komponente verknüpft und <code>aria-activedescendant</code> dazu benutzt, um einen "virtuellen" Fokus zu verwalten. (<a class="external text" href="../../../../An_Overview_of_Accessible_Web_Applications_and_Widgets" rel="nofollow" title="https://developer.mozilla.org/An_Overview_of_Accessible_Web_Applications_and_Widgets">Mehr Informationen über ARIA finden Sie indieser Übersicht</a>).</p>
<p>The <code>aria-activedescendant</code> property identifies the ID of the descendent element that currently has the virtual focus. The event handler on the container must respond to key and mouse events by updating the value of <code>aria-activedescendant</code> and ensuring that the current item is styled appropriately (for example, with a border or background color).</p>
<p>Die Eigenschaft <code>aria-activedescendent</code> enthält die ID des untergeordneten Elements, das aktuell fokussiert ist. Der Event-Handler des Containers muss auf Tastatur- und Mauseingaben reagieren, den Wert von <code>aria-activedescendent</code> aktualisieren und sicherstellen, dass die Darstellung des Elements entsprechend angepasst wird (z.B. Rahmen oder Hintergrundfarbe).</p>
<h5 id="Tipps_2">Tipps</h5>
<h6 id="scrollIntoView">scrollIntoView</h6>
<p>Note that the use of this pattern requires the author to ensure that the current <em>focused</em> widget is scrolled into view. You should be able to use the {{ domxref("element.scrollIntoView()") }} function, but we recommend confirming this works for you in your target browsers using the <a class="external text" href="http://www.quirksmode.org/dom/tests/scrollintoview.html" rel="nofollow">quirksmode test</a>.Bei der Benutzung dieses Musters muss der Entwickler sicherstellen, dass das aktuell <em>fokussierte</em> Element in Sichtweite gescrollt wird. Für diesen Zweck kann die Funktion <code>element.scrollIntoView()</code> eingesetzt werden. Überprüfen Sie jedoch unbedingt mit dem <a class="external text external-icon" href="http://www.quirksmode.org/dom/tests/scrollintoview.html" rel="nofollow">Quirksmode-Test</a>, ob dies für ihre Browser, die unterstützt werden sollen, fehlerfrei funktioniert.</p>
<h6 id="Probleme">Probleme</h6>
<ul>
<li><a class="external text" href="http://www.quirksmode.org/dom/w3c_cssom.html" rel="nofollow">quirksmode meldet Pobleme bei Opera und Konqueror</a></li>
<li><a class="external text" href="https://bugzilla.mozilla.org/show_bug.cgi?id=450405" rel="nofollow">Bug ab Firefox 3.0.1</a></li>
</ul>
<h3 id="Allgemeine_Richtlinien">Allgemeine Richtlinien</h3>
<h4 id="Benutzung_von_onkeydown_um_auf_Tastendrücke_zu_reagieren_(nicht_onkeypress)">Benutzung von onkeydown, um auf Tastendrücke zu reagieren (nicht onkeypress)</h4>
<p>Der Internet Explorer führt <code>keypress</code>-Events für nicht-alpahnumerische Zeichen nicht aus. Benutzen Sie stattdessen das <code>onkeydown</code>-Event.</p>
<h4 id="Tastatur-_und_Mausbedienung_sollte_konsistent_sein">Tastatur- und Mausbedienung sollte konsistent sein</h4>
<p>Um sicherzustellen, dass Benutzereingaben unabhängig vom Eingabegerät konstistent sind, sollten Tastatur- und Maus-Eventhandler denselben Code verwenden. Zum Beispiel sollte der Code, womit der <code>tabindex</code> oder das Aussehen festgelegt wird, wenn die Pfeiltasten benutzt werden, auch für die Mausklick-Handler verwendet werden, damit dieselben Änderungen stattfinden.</p>
<h4 id="Aktivierung_von_Elementen_per_Tastatur">Aktivierung von Elementen per Tastatur</h4>
<p>Damit die Tastatur für die Aktivierung von Elementen benutzt werden kann, sollte alle Handler, die mit der Mausevents verknüpft sind, auch mit Tastaturevents verknüpft werden. Soll z.B. mit der Enter-Taste ein Element aktiviert werden können, welches über einen Maushandler <code>onclick="doSomething()"</code> mit der Maus verknüpft ist, dann sollte die Funktion <code>doSomething()</code> auch über ein <code>keydown</code>-Event mit der Tastatur verknüpft werden: <code>onkeydown="return event.keyCode != 13 || doSomething();"</code>.</p>
<h4 id="Verwenden_Sie_nicht_focus_für_das_Styling_(falls_Kompatibilität_mit_IE_7_und_ältereren_Browsern_notwendig)">Verwenden Sie nicht :focus für das Styling (falls Kompatibilität mit IE 7 und ältereren Browsern notwendig)</h4>
<p>Der Internet Explorer 7 und ältere Versionen unterstützen den Pseudoselektor <code>:focus</code> nicht. Aus diesem Grund sollte er für die Gestaltung von fokussierten Elementen nicht verwendet werden. Stattdessen kann die Darstellung über einen <code>onfucus</code>-Eventhander verändert werden, z.B. indem ein CSS-Style Name dem <code>class</code>-Attribut hinzugefügt wird.</p>
<h4 id="Kontinuierliches_Anzeigen_des_Fokus_für_Elemente_mit_tabindex-1_die_programmatisch_fokussiert_werden"><span style="color: rgb(0, 0, 0);"><span class="toctext">Kontinuierliches Anzeigen des Fokus für Elemente mit tabindex="-1", die programmatisch fokussiert werden</span></span></h4>
<p>Der Internet Explorer zeigt die Fokusumrandung für Elemente nicht automatisch an. Die Hervorhebung des fokussierten Elementes muss daher per JavaScript, entweder durch die Änderung der Hintergrundfarbe (z.B. <code>this.style.backgroundColor = "gray"</code>) oder Anzeige eines gepunkteten Rahmen (z.B. <code>this.style.border = "1px dotted invert"</code>) erfolgen. Entscheiden Sie sich für die zweite Vorgehensweise, sollten die Elementen von Anfang an einen unsichtbaren 1px-Rahmen besitzen, damit sie nicht größer werden, wenn der Rahmen angezeigt wird (Rahmen nehmen Platz in Anspruch und beim IE sind CSS-Outlines nicht implementiert).</p>
<h4 id="Verwendete_Tastendrücke_sollten_keine_Browserfunktionen_auslösen">Verwendete Tastendrücke sollten keine Browserfunktionen auslösen</h4>
<p>Wenn eine Komponente auf Tastendrücke reagiert, sollte verhindert werden, dass der Browser diese Tastendrücke verarbeitet (z.B. Scrollen mit den Pfeiltasten), indem bei Event-Handlern ein Return-Code angegeben wird. Der Rückgabewert <code>false</code> verhindert, dass das Event an den Browser weitergereicht wird.</p>
<p>Hierzu ein Beispiel:</p>
<pre><code><span tabindex="-1" onkeydown="return handleKeyDown();"></code></pre>
<p>Gibt die Funktion <code>handleKeyDown()</code> den Wert <code>false</code> zurück, wird das Event übernommen und der Browser so davon abgehalten auf den Tastendruck zu reagieren.</p>
<h4 id="Abweichendes_Verhalten_bei_wiederholten_Tastendrücken">Abweichendes Verhalten bei wiederholten Tastendrücken</h4>
<p>Je nach Betriebssystem kann es leider vorkommen, dass bei wiederholten Tastendrücken <code>onkeydown</code>-Events wiederholt ausgeführt werden oder auch nicht.</p>
|