<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>protofunc()</title>
	<atom:link href="http://www.protofunc.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.protofunc.com</link>
	<description></description>
	<lastBuildDate>Thu, 11 Mar 2010 18:42:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Das Problem mit dem HTML 5 Video Element</title>
		<link>http://www.protofunc.com/2010/01/19/das-problem-mit-dem-html-5-video-element/</link>
		<comments>http://www.protofunc.com/2010/01/19/das-problem-mit-dem-html-5-video-element/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 22:48:23 +0000</pubDate>
		<dc:creator>alexander farkas</dc:creator>
				<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[deutsch]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.protofunc.com/?p=37</guid>
		<description><![CDATA[Ich arbeite in letzter Zeit immer wieder mit dem HTML 5 Video Element. Bis auf einige kleinen Problemchen mit der API sowie einigen grausamen Implementierungsbug im Safari (betrifft nicht Chrome), bin ich eigentlich ganz zufrieden.
Es gibt aber letztendlich eine Sache die mich extrem rasend macht. Schaut man sich die Youtube HTML5 Demo an und vergleicht [...]]]></description>
			<content:encoded><![CDATA[<p>Ich arbeite in letzter Zeit immer wieder mit dem HTML 5 Video Element. Bis auf einige kleinen Problemchen mit der API sowie einigen grausamen Implementierungsbug im Safari (betrifft nicht Chrome), bin ich eigentlich ganz zufrieden.</p>
<p>Es gibt aber letztendlich eine Sache die mich extrem rasend macht. Schaut man sich die <a href="http://www.youtube.com/html5">Youtube HTML5 Demo</a> an und vergleicht diese mit der Spezifikation wird einem klar, daß Youtube mit HTML5 nie so aussehen kann, wie diese Demo einem glauben machen will.</p>
<p>Die Demo zeigt einen Fullscreen-Button. Leider ist die <a href="http://www.w3.org/TR/html5/video.html">HTML5 Spezifikation</a> hier sehr einduetig. Einerseits ist keine API für einen möglichen Fullscreen-Modus definiert andererseits werden Browserhersteller mit fetter, roter Schrift ausdrücklich davor gewarnt, eine solche zu implementieren. Als Begründung wird auf mögliche &#8220;Nervigkeiten&#8221; sowie Angst vor Sicherheitsproblemen, genauer Phishing Attacken, abgestellt.</p>
<p>Letztendlich ist die Begründung vollkommen überholt und daneben. Das Security Argument stimmt nicht, da</p>
<ul>
<li>ein Videoelement beim Starten des Vollbildmous grundsätzlich einen entsprechenden Hinweis zeigen soll</li>
<li>ein Videoelement im Vollbildmodus, unabhängig vom Vorhandensein des controls-Attribut, die Kontrollelemente anzeigen muß</li>
<li>es im Vollbildmodus gar nicht möglich ist &#8211; und das wäre das eigentliche Sicherheitsrisiko &#8211; Tastaturevents abzufangen</li>
</ul>
<p>Auch das Risiko einer Belästigung des Users ist gering, wenn man es mit ähnlichen Einschränkungen implementieren würde wie dies bei Adobe Flash getan wurde. Gerade Flash, welches häufig für nervige Dinge wie Werbebanner eingesetzt wird, hat eine API für den Fullscreenmodus, anstatt daß dies mich nervt, empfinde ich es als extrem nützlich.</p>
<p>Hier lag wohl auch augenscheinlich das Problem. Eine API für den Fullscreenmodus wurde mit Methoden wie window.open oder window.resize verglichen, ohne zu erkennen, daß das Anschauen von Videos im Vollbildmodus ein wesentlich nützlicheres Feature ist als das ungefragte Öffnen von Popups und Verschieben von Browserfenstern.</p>
<p>Meine große Hoffnung liegt nun darin, daß entweder irgendein Browser (zum Beispiel: Chrome 4 oder 5 oder Internet Explorer 9) aus der Reihe tanzt und zeigt wie man ein cooles, sicheres Feature implementiert oder daß bei der Zugänglichkeits- (oder vielleicht auch Usability-) überarbeitung des Elements auffällt, daß ein Fullscreenmodus nicht allein mit der rechten Maustaste als Kontextmenü realisiert werden darf.</p>
<p>Ich kotze.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protofunc.com/2010/01/19/das-problem-mit-dem-html-5-video-element/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>widgetExtend: jQuery UI Widgets erweitern</title>
		<link>http://www.protofunc.com/2010/01/09/widgetextend-jquery-ui-widgets-erweitern/</link>
		<comments>http://www.protofunc.com/2010/01/09/widgetextend-jquery-ui-widgets-erweitern/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 14:21:38 +0000</pubDate>
		<dc:creator>alexander farkas</dc:creator>
				<category><![CDATA[deutsch]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.protofunc.com/?p=35</guid>
		<description><![CDATA[Letztendlich gibt es mehrere Möglichkeiten vorhandene jQuery UI Widgets zu erweitern. Die hierzu am häufigsten verwendete Methode ist die $.extend. Was in etwa so aussieht:

//neues a11yTabs erweitert tabs
$.widget('ui.a11yTabs', $.extend({}, $.ui.tabs.prototype, {
	select: function(){
		$.ui.tabs.prototype.select.apply(this, arguments);
	}
});
// tabs selbst erweitern
//altes select sichern
var oldSelect = $.ui.tabs.prototype.select;
$.extend($.ui.tabs.prototype, {
	select: function(){
		oldSelect.apply(this, arguments);
	}
});

Überschreibt man hierdurch eine bereits vorhandene Funktion, welche man noch nutzen möchte, [...]]]></description>
			<content:encoded><![CDATA[<p>Letztendlich gibt es mehrere Möglichkeiten vorhandene jQuery UI Widgets zu erweitern. Die hierzu am häufigsten verwendete Methode ist die $.extend. Was in etwa so aussieht:</p>
<pre class="brush: jscript;">
//neues a11yTabs erweitert tabs
$.widget('ui.a11yTabs', $.extend({}, $.ui.tabs.prototype, {
	select: function(){
		$.ui.tabs.prototype.select.apply(this, arguments);
	}
});
// tabs selbst erweitern
//altes select sichern
var oldSelect = $.ui.tabs.prototype.select;
$.extend($.ui.tabs.prototype, {
	select: function(){
		oldSelect.apply(this, arguments);
	}
});
</pre>
<p>Überschreibt man hierdurch eine bereits vorhandene Funktion, welche man noch nutzen möchte, muß man diese, wie im zweiten Beispiel geschehen, vor dem überschreiben zwischenspeichern, so daß man weiterhin auf die Originalmethode Zugriff hat.</p>
<p>Eine relativ elegante Schreibweise hierzu findet sich bei <a href="http://www.felixnagel.com/blog/permalink/78/">Felix Nagel</a>, welcher folgenden einfachen Code zeigt:</p>
<pre class="brush: jscript;">
// extends original ui.tabs widget
$.extend($.ui.tabs.prototype,{
	// copy original method
	_original_init: $.ui.tabs.prototype._init,
	// when widget is initiated
	_init: function() {
		var self = this, options = this.options;
		// fire original method
		self._original_init();

		// now we can do some accessibility stuff
	}
});
</pre>
<p>Wenn man derartiges drei- bis viermal schreiben muß, kommt man sich aber doch recht schnell etwas blöd vor. Als sich mir eben dieses Problem stellte, hatte ich daher folgende kleine extend-Methode geschrieben (noch nicht völlig durchgetestet):</p>
<pre class="brush: jscript;">
var slice = Array.prototype.slice;
$.widgetExtend = function(widget, exts){
	var args = arguments;

	$.each(exts, function(name, fn){
		if( name in widget ){
			if( fn &amp;&amp; $.isFunction(fn) ){
				fn._super = widget[name];
			} else {
				widget['_super'+ name] = widget[name];
			}
		}
		widget[name] = fn;
	});

	if( args.length &gt; 2 ){
		args = slice.call(arguments, 2);
		args.unshift(widget);
		widget = $.widgetExtend.apply(this, args);
	}

	return widget;
};
</pre>
<p>Mit dieser kleinen Methode kann man, dannn ohne lästiges zwischenspeichern über arguments.callee._super auf die Hauptmethode zugreifen:</p>
<pre class="brush: jscript;">
//neues a11yTabs erweitert tabs
$.widget('ui.a11yTabs', $.widgetExtend({}, $.ui.tabs.prototype, {
	select: function(){
                //$.ui.tabs.prototype.select kann eigentlich auch noch verwendet werden
		arguments.callee._super.apply(this, arguments);
	}
});
// tabs selbst erweitern

$.widgetExtend($.ui.tabs.prototype, {
	select: function(){
		arguments.callee._super.apply(this, arguments);
	}
});
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.protofunc.com/2010/01/09/widgetextend-jquery-ui-widgets-erweitern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WAI-ARIA &#8211; Epic Fail: Reste fressen</title>
		<link>http://www.protofunc.com/2010/01/03/wai-aria-epic-fail-reste-fressen/</link>
		<comments>http://www.protofunc.com/2010/01/03/wai-aria-epic-fail-reste-fressen/#comments</comments>
		<pubDate>Sun, 03 Jan 2010 22:55:04 +0000</pubDate>
		<dc:creator>alexander farkas</dc:creator>
				<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.protofunc.com/?p=34</guid>
		<description><![CDATA[Nicht wenige Aria Beispiele beschränken sich auf das wesentliche und statten unsemantisches HTML, insbesondere div und span-Elemente, mit den jeweiligen Aria-Attributen aus. In der Praxis wird regelmäßig semantisches HTML als Grundlage genommen. Gleichzeitig passieren hierbei jedoch zwei vermeidbare Fehler.
1. Die Verschachtelung der Aria-Attribute folgt der semantischen HTML-Struktur und nicht der Aria-Spezifikation
Ein typisches Beispiel ist eine [...]]]></description>
			<content:encoded><![CDATA[<p>Nicht wenige Aria Beispiele beschränken sich auf das wesentliche und statten unsemantisches HTML, insbesondere div und span-Elemente, mit den jeweiligen Aria-Attributen aus. In der Praxis wird regelmäßig semantisches HTML als Grundlage genommen. Gleichzeitig passieren hierbei jedoch zwei vermeidbare Fehler.</p>
<h2>1. Die Verschachtelung der Aria-Attribute folgt der semantischen HTML-Struktur und nicht der Aria-Spezifikation</h2>
<p>Ein typisches Beispiel ist eine Menüleiste, welche mit verschachtelten Listen aufgebaut wurde:</p>
<pre class="brush: xml;">
&lt;ul role=&quot;menubar&quot;&gt;
	&lt;li role=&quot;menuitem&quot; aria-haspopup=&quot;true&quot;&gt;
		&lt;a href=&quot;#&quot; tabindex=&quot;0&quot;&gt;Menubaritem&lt;/a&gt;
		&lt;ul role=&quot;menu&quot; aria-hidden=&quot;true&quot;&gt;
			&lt;!-- weitere menuitems --&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>Schaut man sich diese Struktur an und vergleicht sie mit der Aria-Spezifikation sollte auffallen, daß</p>
<ul>
<li>der Menüeintrag das interaktive Objekt ist und nicht der Link</li>
<li>der Link innerhalb eines Menüs eigentlich ein artfremdes Objekt ist</li>
<li>ein Untermnü/Poupup-Menü kein Kind des dazugehörigen Menüitems</li>
</ul>
<p>Ein entsprechend korrigiertes HTML könnte demnach wie folgt aussehen:</p>
<pre class="brush: xml;">
&lt;ul role=&quot;menubar&quot;&gt;
	&lt;li role=&quot;presentation&quot;&gt;
		&lt;a role=&quot;menuitem&quot; aria-haspopup=&quot;true&quot; href=&quot;#&quot; tabindex=&quot;0&quot;&gt;Menubaritem&lt;/a&gt;
		&lt;ul role=&quot;menu&quot; aria-hidden=&quot;true&quot;&gt;
			&lt;!-- weitere menuitems --&gt;
		&lt;/ul&gt;
	&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>Doch auch diese HTML-Struktur ist letztendlich fehlerhaft und wird &#8211; insbesondere von Jaws, dem marktführendne Screenreader &#8211; recht unangenehm gelesen.</p>
<h2>2. Das Reste fressen</h2>
<p>Überall im Netz findet man leider Scripte, die die HTML-Struktur so verändern, daß der Screenreader semantische Überreste der alten HTML-Struktur vorgeworfen bekommt. Nachfolgend ein paar Beispiele mit dem typischen a[href]-Problem:</p>
<pre class="brush: xml;">
&lt;!-- Tabs --&gt;
&lt;a href=&quot;#&quot; role=&quot;tab&quot; tabindex=&quot;-1&quot; aria-selected=&quot;false&quot; aria-controls=&quot;tab-2&quot;&gt;Ein Tab&lt;/a&gt;

&lt;!-- Menü --&gt;
&lt;a href=&quot;#&quot; role=&quot;menuitem&quot; tabindex=&quot;-1&quot; aria-haspopup=&quot;true&quot;&gt;Ein Menüitem&lt;/a&gt;

&lt;!-- Menübutton (hier gibt es eine kleine Ausnahme) --&gt;
&lt;a href=&quot;#&quot; role=&quot;button&quot; aria-haspopup=&quot;true&quot;&gt;Menübutton&lt;/a&gt;
</pre>
<p>Hierbei wird gerne übersehen, daß das href-Attribut eines Anchor-Elements, gleichzeitig immer als Accessibility-Wert des Links an die Zugänglichkeitsschnittstelle übergeben wird. Hat der Link keinen Namen, lesen einige Screenreader als Hilfe eben diesen Wert vor. Nun wurde jedoch in allen Beispielen die Rolle des Anchor-Elements auf eine andere Rolle gemappt und viele Screenreader lesen dann ebenfalls den Wert vor, auch wenn der Name vorhanden ist. Hierbei ist erschwerend zu beachten, daß nicht der Inhalt des HTML-Attributs vorgelesen wird, sondern die href-DOM-Eigenschaft, welche die &#8211; vom Browser berechnete &#8211; absolute URL darstellt.</p>
<p>Auf dieser Seite würde der Screenreader Jaws beim Fokusieren des oben dargestellten Menüeintrags folgendes vorlesen:</p>
<p>Menüeintrag Ein Menüitem H T T P Doppelpunkt Schrägstrich Schrägstrich w w w Punkt protofunc Punkt com Schrägstrich 2010 Schrägstrich 01 Schrägstrich 03 Schrägstrich wai Bindestrich aria Bindestrich epic Bindestrich fail Bindestrich reste Bindestrich fressen Schrägstrich Raute Untermenü</p>
<p>Im Ergebnis läßt sich folgendes sagen, wenn ein Script solch ein HTML produziert, sollte man dieses Script auf keinen Fall einsetzen. Es ist offensichtlich, daß dieser Code nicht einmal mit dem marktführenden Screenreader getestet wurde und es könnten daher noch weitere Bugs vorhanden.</p>
<p>Ein bereinigtes HTML könnte wie folgt aussehen:</p>
<pre class="brush: xml;">
&lt;!-- Tabs --&gt;
&lt;a role=&quot;tab&quot; tabindex=&quot;-1&quot; aria-selected=&quot;false&quot; aria-controls=&quot;tab-2&quot;&gt;Ein Tab&lt;/a&gt;

&lt;!-- Menü --&gt;
&lt;a role=&quot;menuitem&quot; tabindex=&quot;-1&quot; aria-haspopup=&quot;true&quot;&gt;Ein Menüitem&lt;/a&gt;

&lt;!-- Menübutton (hier gibt es eine kleine Ausnahme) --&gt;
&lt;a role=&quot;button&quot; aria-haspopup=&quot;true&quot; tabindex=&quot;0&quot;&gt;Menübutton&lt;/a&gt;
</pre>
<p>Diese Struktur &#8211; insbesondere beim Menübutton &#8211; führt zu einigen kleineren Problemen, die man beim Coden von CSS/JS berücksichtigen muß. Die Lösung(en) hierzu würde(n) allerdings den Rahmen sprengen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protofunc.com/2010/01/03/wai-aria-epic-fail-reste-fressen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WAI-ARIA &#8211; Epic Fail: Wenn der Screenreader nicht mehr aufhören will zu plappern</title>
		<link>http://www.protofunc.com/2009/12/30/wai-aria-epic-fail-wenn-der-screenreader-nicht-mehr-aufhoren-will-zu-plappern/</link>
		<comments>http://www.protofunc.com/2009/12/30/wai-aria-epic-fail-wenn-der-screenreader-nicht-mehr-aufhoren-will-zu-plappern/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 17:02:59 +0000</pubDate>
		<dc:creator>alexander farkas</dc:creator>
				<category><![CDATA[accessibility]]></category>
		<category><![CDATA[deutsch]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.protofunc.com/?p=33</guid>
		<description><![CDATA[Aria Live Regions gehören zu den spannenderen Attributen bei Wai-Aria und haben &#8211; trotz der noch schlechten Unterstützung durch Screenreader &#8211; für einiges an Aufsehen gesorgt. Das Aria Best Practices Dokument ist ein guter Einstieg in Liveregions. Neben dem Attribut aria-live können die Attribute aria-busy, aria-relevant und aria-atomic das Vorleseverhalten im Screenreader beeinflußen. Bei Liveregions [...]]]></description>
			<content:encoded><![CDATA[<p>Aria Live Regions gehören zu den spannenderen Attributen bei Wai-Aria und haben &#8211; trotz der noch schlechten Unterstützung durch Screenreader &#8211; für einiges an Aufsehen gesorgt. Das <a href="http://www.w3.org/WAI/PF/aria-practices/#docmgt">Aria Best Practices Dokument</a> ist ein guter Einstieg in Liveregions. Neben dem Attribut aria-live können die Attribute aria-busy, aria-relevant und aria-atomic das Vorleseverhalten im Screenreader beeinflußen. Bei Liveregions muß immer bedacht werden, daß ein ständig oder zu viel plappernder Text nervt und den User eher bei der Erfüllung seiner Aufgaben stört als weiterhilft. Dieses Problem wird allerdings vom oben genannten Best Practice Dokument mehr als ausgiebig beschrieben, so daß selten Fehlimplementierungen zu finden sind.</p>
<h2>Wann Liveregions überhaupt Sinn machen?</h2>
<p>Das grundsätzliche Mißverständnis von Liveregions liegt darin, daß viele Entwickler Liveregions als generelle Antwort auf das Problem von dynamischen Änderungen des Contents sehen. Sie also meinen, das ein HTML-Bereich immer als Liveregion ausgezeichnet werden sollte, wenn sich der Content, zum Beispiel aufgrund einer Ajax-Response, dynamisch ändert.</p>
<p>Hierbei wird allzu gerne folgender Text des Best Practices Dokuments überlesen/mißverstanden:</p>
<blockquote><p>Live regions enable assistive technologies, such as screen readers, to be informed of updates without losing the users&#8217; place in the content.</p></blockquote>
<p>Damit hört sich das Feature &#8220;Liveregion&#8221; ziemlich cool an (und ist es auch). Man kann nämlich ohne den Fokus des Users ändern zu müßen, Informationen vorlesen laßen: Zum Beispiel kann ein Warenkorb darüber informieren, daß das Produkt nun erfolgreich im Warenkorb abgelegt wurde, ohne daß der User wegbewegt wird, er also weiterhin innerhalb des Produktskatalogs surfen kann. Er kann über neu eingegangene Chat-Nachrichten informiert werden, ohne daß er bei seiner eigenen Eingabe einer Nachricht gestört wird. Oder der User kann mit Hilfe der Rolle alert, welche implizit eine Liveregion ist, auf Fehler innerhalb eines Formularprozeßes aufmerksam gemacht werden, ohne ihn am weiteren Ausfüllen anderer Formularfelder zu behindern.</p>
<p>Leider wird die Kehrseite hieraus nicht deutlich gemacht und es kommt dadurch zur Fehlimplementierung. Diese Kehrseite könnte beispielsweise wie folgt lauten:</p>
<p>Liveregions ermöglichen es assistiven Technologien über geänderte Inhalte informiert zu werden, ohne daß der User mit diesen Inhalten &#8211; zumindest sofort &#8211; interagieren kann/soll/muß.</p>
<p>Ist der Text etwas länger, stärker strukturiert oder bietet gar Eingabemöglichkeiten wie Links, Formulare oder andere Eingabewidgets, möchte der User diesen Text nicht dumpf vorgelesen bekommen, er möchte mit diesem interagieren. Hierzu muß er jedoch den aktuellen Bereich verlaßen und zum neu geänderten Content gebracht werden. Dies ist eine Aufgabe, die von Screenreadern in Kombination mit Liveregions (noch) nicht erfüllt wird (eine gewisse Ausnahme stellt hier der Screenreader <a href="http://live.gnome.org/Orca/Firefox/LiveRegions">Orca dar, welcher auf Wunsch des Users auch zu einer Liveregion</a> springt), von der Aria-Spezifikation nicht gefordert wird (obwohl es Sinn machen würde), aber letztendlich auch gar nicht erfüllt werden muß.</p>
<p>Für diese Art von Content-Änderung benötigt man nämlich kein Aria. Die Lösung ist kinderleicht zu impelentieren und funktioniert auch in vielen nicht Aria-fähigen Screenreader-Browser-Kombinationen. Die Lösung heißt focus.</p>
<p>Wenn wir beispielsweise folgendes geändertes HTML haben&#8230;</p>
<pre class="brush: xml;">
&lt;div id=&quot;live-content&quot;&gt;
	&lt;h2 tabindex=&quot;-1&quot;&gt;Überschrift von neuem Content&lt;/h2&gt;
	&lt;!-- weiterer Inhalt --&gt;
&lt;/div&gt;
</pre>
<p>können wir mit folgender Funktion &#8230;</p>
<pre class="brush: jscript;">
function setFocus(elem){
	setTimeout(function(){
		try {
			elem.focus();
		} catch(e){}
	}, 0);
}
</pre>
<p>den Fokus auf folgende Weise&#8230;</p>
<pre class="brush: jscript;">
setFocus(document.getElementById('live-content').getElementsByTagName('h2')[0]);
</pre>
<p>ganz einfach verschieben, so daß die Überschrift des neuen Contents vorgelesen und der User mit dem neuen Content interagieren kann. Das uncolle an dieser einfachen Art für Zugänglichkeit zu sorgen, ist einzig und alleine, daß wir im Prinzip praktisch keine neue Technik einsetzen und es potentiell die Möglichkeit gibt, daß es auch in &#8220;älteren&#8221; Screenreadern funktionieren könnte.</p>
<p>Wer dies in möglichst vielen Screenreadern zum Laufen bringen möchte, sollte sich <a href="http://www.protofunc.com/2009/10/11/der-grose-screenreader-focus-test/">den großen Screenreader Fokus Test</a> durchlesen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protofunc.com/2009/12/30/wai-aria-epic-fail-wenn-der-screenreader-nicht-mehr-aufhoren-will-zu-plappern/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>WAI-ARIA &#8211; Epic Fail (Too much accessibility &#8211; good intentions, badly implemented)</title>
		<link>http://www.protofunc.com/2009/12/30/wai-aria-epic-fail-too-much-accessibility-good-intentions-badly-implemented/</link>
		<comments>http://www.protofunc.com/2009/12/30/wai-aria-epic-fail-too-much-accessibility-good-intentions-badly-implemented/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 17:02:47 +0000</pubDate>
		<dc:creator>alexander farkas</dc:creator>
				<category><![CDATA[accessibility]]></category>
		<category><![CDATA[deutsch]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.protofunc.com/?p=32</guid>
		<description><![CDATA[Wenn Frontend-Entwickler neues Spielzeug bekommen, passiert eigentlich immer das gleiche. Sie laden sich, wenn nicht bereits geschehen, die neueste Alpha/Beta Version von Safari, Firefox und / oder Opera herunter und fangen dann an, die neuen Techniken zu testen, zu experimentieren und schließlich einzusetzen.
Bei WAI-Aria ist dies anders. Hier wird zwar bereits von einigen fleißig eingesetzt, [...]]]></description>
			<content:encoded><![CDATA[<p>Wenn Frontend-Entwickler neues Spielzeug bekommen, passiert eigentlich immer das gleiche. Sie laden sich, wenn nicht bereits geschehen, die neueste Alpha/Beta Version von Safari, Firefox und / oder Opera herunter und fangen dann an, die neuen Techniken zu testen, zu experimentieren und schließlich einzusetzen.</p>
<p>Bei WAI-Aria ist dies anders. Hier wird zwar bereits von einigen fleißig eingesetzt, aber kaum ein Entwickler kommt auf die Idee sich die neueste Version von Jaws herunterzuladen, zu installieren und zu testen. Hinzu kommt, daß viele Frontendentwickler eigentlich mehr so etwas wie theologisch und / oder philosophisch veranlagte Semantik-Professoren der HTML-Meta-Ebene sind, als gestandene Entwickler. Anstatt Aria so zu implemtieren, daß es funktioniert, wird lieber nach einem tieferen Sinn gesucht und die Aria Attribute und das Verhalten implementiert, welches nach der jeweiligen tiefen, manchmal religiösen, Überzeugung das semantisch näher liegende ist.</p>
<p>Nicht anders ist es zu erklären, daß mit Aria ausgetattete Javascript Widgets häufig größere Barrieren darstellen, als die identische Widget-Version, welche überhaupt kein Aria einsetzt.</p>
<p>Im Prinzip ist die Aria-Entwicklung ziemlich leicht, wenn man sich an die Fakten hält:</p>
<ul>
<li>Was sagt das <a href="http://www.w3.org/WAI/PF/aria-practices/">Aria-Best Practice Dokument</a> (für Entwickler wichtiger als die <a href="http://www.w3.org/TR/wai-aria/">Spezifikation</a>)</li>
<li>Was für Accessibility-Informationen und welches Verhalten zeigen native, zugängliche Applikationen (<a href="http://www.microsoft.com/downloads/details.aspx?familyid=3755582A-A707-460A-BF21-1373316E13F0">MSAA-Inspect</a> und/oder <a href="http://www.eclipse.org/actf/downloads/tools/accprobe/index.php">Accessibility Probe</a>)</li>
<li>Mit welchen Aria-Attributen erreiche ich die selben Accessibility-Informationen im HTML</li>
<li>Und das wichtigste: Was liest mir die aktuellste Jaws-Version im aktuellsten Firefox vor (Vorsicht: Nicht wenige User verwenden häufig ältere Jaws-Versionen und den Internet Explorer 7/8)</li>
</ul>
<p>Im Ergebnis tue ich mich mit diesem Zustand schwer. Die meisten Veröffentlichungen in diesem Blog zum Thema Barrierefreiheit gehen auf ein einziges Gefühl zurück, nämlich Wut über die Werke anderer Entwickler. In der Regel schreibe ich erst einen bitter bösen &#8220;Pranger-Artikel&#8221;, um diesen dann zu verwerfen und einfach ein Tutorial zu schreiben, wie man es hätte besser machen können, ohne den Bezug zum Original zu nennen. Ich glaube letztendlich, daß beide Formate nämlich Pranger-Artikel einerseits und Tutorial andererseits nicht weiterhelfen und wechsel hiermit nun das Format. Die WAI-Aria Epic Fail-Reihe soll nicht unbedingt zeigen, wie man es besser macht, sondern typische Fehlansätze bei der Aria Entwicklung aus der Praxis aufgreifen und darauf aufmerksam machen, ohne dabei Texte bzw. Scripte bzw. ihre Autoren/Entwickler an den Pranger zu stellen. Obwohl ich selbst inzwischen, gerade durch Beschäftigung mit Aria &#8211; merke, daß ich häufig gar kein Aria brauche, um Widgets überhaupt zugänglich zu machen, werde ich mich nur auf Aria konzentrieren, da hier zumindest die Zukunft zugänglicher Widgets liegt.</p>
<p>Den Anfang machen <a href="http://www.protofunc.com/2009/12/30/wai-aria-epic-fail-wenn-der-screenreader-nicht-mehr-aufhoren-will-zu-plappern/">die Aria-Liveregions</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protofunc.com/2009/12/30/wai-aria-epic-fail-too-much-accessibility-good-intentions-badly-implemented/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>mwheelIntent: Das gebrauchstaugliche mouswheel-Event</title>
		<link>http://www.protofunc.com/2009/12/29/mwheelintent-das-gebrauchstaugliche-mouswheel-event/</link>
		<comments>http://www.protofunc.com/2009/12/29/mwheelintent-das-gebrauchstaugliche-mouswheel-event/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 18:43:33 +0000</pubDate>
		<dc:creator>alexander farkas</dc:creator>
				<category><![CDATA[Usability]]></category>
		<category><![CDATA[deutsch]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.protofunc.com/?p=31</guid>
		<description><![CDATA[Eine Möglichkeit die Usability von Javascript Widgets zu erhöhen, ist es eine reichhaltige Interaktionsmöglichkeit zu bieten. D.h. beispielsweise, daß ein Carousel nicht nur durch einen Click auf die Vorwärts-/Rückwärts-Schalter, sondern beispielsweise auch durch Tastatur oder eben das Mausrad bedient werden kann.
Javascript Widgets, die typischwerweise mit dem Mausrad bedient werden können, sind Karten wie Googlemaps, Yahoo [...]]]></description>
			<content:encoded><![CDATA[<p>Eine Möglichkeit die Usability von Javascript Widgets zu erhöhen, ist es eine reichhaltige Interaktionsmöglichkeit zu bieten. D.h. beispielsweise, daß ein Carousel nicht nur durch einen Click auf die Vorwärts-/Rückwärts-Schalter, sondern beispielsweise auch durch Tastatur oder eben das Mausrad bedient werden kann.</p>
<p>Javascript Widgets, die typischwerweise mit dem Mausrad bedient werden können, sind Karten wie Googlemaps, Yahoo Maps, Scrollbar-Ersetzungen sowie Laufbänder/Carousels. Mit dem Hinzufügen einer einfachen Mausradbehandlung zu diesen Widgets verursacht man jedoch in der Regel gleichzeitig ein größeres Usability-Problem. Denn diese Widgets sind in der Regel innerhalb eines Dokuments angelegt, welches ebenfalls mit dem Mausrad bedient werden kann. Möchte der User beispielsweise das Dokument mit dem Mausrad scrollen und kommt dabei eher zufällig auf ein Widget, welches ebenfalls per Mausrad gesteuert werden kann, fängt gerade dieses Widget die Mausradeingabe ab. Dies dürfte vom User nicht gewüsncht sein und ihn mehr verärgern als daß es ihn freut, daß er das Widget auch mit dem Mausrad bedienen kann.</p>
<p>Die Lösung für dieses Problem ist relativ einfach (und ist alleine deshalb bereits genial) und wird beispielsweise in einigen nativen Appliaktionen wie beispielsweise Firefox genutzt, um zu entscheiden, welches Widget gerade mit dem Mausrad bedient werden soll.</p>
<p>Hat der User nämlich in einem bestimmten &#8220;Mausradinteraktionsbereich&#8221; angefangen das Mausrad zu bedienen, so erhält dieser Bereich das Mausrad-Event exklusiv, solange der User sich a) über diesen Bereich bewegt und b) nicht die Maus bewegt, selbst wenn er dabei über andere interaktive Bereiche scrollt.</p>
<p>Ich habe mir erlaubt für eine solche <a href="http://plugins.jquery.com/project/mwheelIntent">Behandlung des Mausradevents ein jQuery-Plugin</a> mit <a href="http://www.protofunc.com/scripts/jquery/mwheelIntent/">mwheelIntent-Demo</a> zu schreiben. Die Nutzung ist relativ einfach:</p>
<pre class="brush: jscript;">
$('div.widget').bind('mwheelIntent', function(e, d){
	//die mausrad implementierung
}):
</pre>
<h2>Wie wurde dies implementiert</h2>
<h3>Das Grundgerüst</h3>
<p>Für alle die es interessiert ein neues tolles custom-Event für jQuery zu schreiben, hier eine kurze Anleitung am Beispiel des mwheelIntent-Codes.</p>
<p>Als 1. definieren wir einige Variablen, welche wir noch benötigen werden. Besondere Beachtung sollte der Variable mwheelI geschenkt werden. Unter der Eigenschaft pos speichern wir mit jeder Mausradbewegung ab, wo sich das Mausrad gerade innerhalb des Viewports befindet, um zu entscheiden, ob der User die Maus zwischenzeitlich bewegt hat. Anfangs setzen wir diese mit jeweils -260 für x und y Koordinate weit aus dem Viewport, so daß anfangs immer von einer Mausbwegung ausgegangen wird.</p>
<p>Die Variable minDif gibt an, um wieviel Pixel der User die Maus mindestens bewegt haben muß, um eine Änderung des &#8220;Mausradinteraktionsbereichs&#8221; zu bewirken. Das eigentliche Kernstück unseres Events befindet sich unter $.event.special.mwheelIntent.</p>
<p>Die Methode setup wird aufgerufen, sobald der 1. mwheelIntent-Handler an einem DOM-Objekt gebindet wird, teardown, wenn der letzte mwheelIntent-Handler wieder entfernt wird. Die Methode handler wird letztendlich durch unser Event-System selbst aufgerufen und stößt das Aufrufen der eigentlich hinzugefügten Handler als eine Art proxy-Handler an. Dieser Methodenname könnte &#8211; meines Wissens nach &#8211; auch anders heißen, es ist jedoch Konvention ihn so zu nennen.</p>
<pre class="brush: jscript;">
(function($){

//einige variablen
var mwheelI = {
			pos: [-260, -260]
		},
	minDif 	= 3,
	doc 	= document,
	root 	= doc.documentElement,
	body 	= doc.body,
	longDelay, shortDelay
;

// das eigentliche event grundgerüst
$.event.special.mwheelIntent = {
	setup: function(){

    },
	teardown: function(){

    },
    handler: function(e, d){

    }
};

// shortcuts  .bind('mwheelIntent', fn) -&gt; .mwheelIntent()
$.fn.extend({
	mwheelIntent: function(fn) {
		return fn ? this.bind(&quot;mwheelIntent&quot;, fn) : this.trigger(&quot;mwheelIntent&quot;);
	},

	unmwheelIntent: function(fn) {
		return this.unbind(&quot;mwheelIntent&quot;, fn);
	}
});

//initialisierung des scrollbaren bereichs
$(function(){
	// falls body anfangs undefined gewesen sein sollte
	body = doc.body;
	// falls der User das cross-browser-mousewheel-Plugin nicht eingebunden hat
	if(!$.fn.mousewheel){
		setTimeout(function(){
			throw('Please include the mousewheel plugin before the mwheelIntent-plugin');
		}, 0);
	}
	//document als immer scrollbaren bereich berücksichtigen
	$(doc).bind('mwheelIntent.mwheelIntentDefault', function(){});
});
})(jQuery);
</pre>
<p>jQuery 1.4 wird zudem die beiden neuen Event-Hooks add und remove einführen, welche mit jedem hinzugefügten bzw. jedem entfernten Handler aufgerufen werden. (<a href="http://brandonaaron.net/blog/2009/06/4/jquery-edge-new-special-event-hooks">Mehr zu den neuen jQuery 1.4 Event hooks</a>). Allerdings brauchen wir diese nicht.</p>
<h3>Die Mausradbehandlung</h3>
<p>Kommen wir nun zu der eigentlichen Implementierung. Unsere setup-Methode fügt letztendlich einen Eventlistener für das normale Mausradevent hinzu, welche unsere Handler Methode aufruft, in dem die Berechnung stattfindet, ob das Mausradevent durchgelassen werden soll oder nicht. Außerdem wird beim Verlassen der Maus aus dem Bereich die Funktion unsetPos aufgerufen, welche unsere eventuell gesetzten Werte auf den Anfangswert zurücksetzt. Bei den Objekten document, html und body wird dieser Listener nicht hinzugefügt, da er hier keinen Sinn machen würde und aufgrund der Tatsache, daß mouseleave ein auf mouseout aufbauendes Special-Event ist, einiges an Performance Kosten würde. Die teardown entfernt beide Listener wieder.</p>
<p>Die handler-Methode verfügt nun über den bereits erwähnten simplen, aber wirkungsvollen Code. Jedesmal wenn der User das Mausrad bewegt, wird die Mausposition abgespeichert und mit der letzten verglichen. Ist das DOM-Objekt mit dem letzten -durch das Mausrad bedienten &#8211; Objekt identisch oder hat der User seitdem die Maus weiter bewegt als in minDif definiert, wird das Event durchgelassen und die gebindeten handler mit der Methode $.event.handle.call(this, e, d); aufgerufen.</p>
<pre class="brush: jscript;">

function unsetPos(){
	if(this === mwheelI.elem){
		mwheelI.pos = [-260, -260];
		mwheelI.elem = false;
		minDif = 3;
	}
}

$.event.special.mwheelIntent = {
	setup: function(){
		var jElm = $(this).bind('mousewheel', $.event.special.mwheelIntent.handler);
		if( this !== doc &amp;&amp; this !== root &amp;&amp; this !== body ){
			jElm.bind('mouseleave', unsetPos);
		}
		jElm = null;
        return true;
    },
	teardown: function(){
        $(this)
			.unbind('mousewheel', $.event.special.mwheelIntent.handler)
			.unbind('mouseleave', unsetPos)
		;
        return true;
    },
    handler: function(e, d){
		var pos = [e.clientX, e.clientY];
		if( this === mwheelI.elem || Math.abs(mwheelI.pos[0] - pos[0]) &gt; minDif || Math.abs(mwheelI.pos[1] - pos[1]) &gt; minDif ){
            mwheelI.elem = this;
			mwheelI.pos = pos;
			e = $.extend({}, e, {type: 'mwheelIntent'});
            return $.event.handle.call(this, e, d);
		}
    }
};
</pre>
<h3>Verfeinerung der Mausradbehandlung</h3>
<p>Dem aufmerksamen Leser wird aufgefallen sein, daß ich die Variable minDif ebenfalls auf 3 zurücksetze, obwohl ich sie gar nicht geändert haben. Außerdem habe ich 2 Variablen (longDelay, shortDelay) deklariert, die noch gar nicht genutzt werden. Dies hat mit einer kleineren Verfeinerung unseres Script zu tun. Hat der User gerade erst das Mausrad gedreht, soll er größere Mausbewegungen machen können, um eine ungewollte Verschiebung der Maus eben durch die Betätigung des Mausrads abzufangen. Dieser Code ist in der handler-Methode untergebracht und sieht wie folgt aus:</p>
<pre class="brush: jscript;">
handler: function(e, d){
	var pos = [e.clientX, e.clientY];
	if( this === mwheelI.elem || Math.abs(mwheelI.pos[0] - pos[0]) &gt; minDif || Math.abs(mwheelI.pos[1] - pos[1]) &gt; minDif ){
		mwheelI.elem = this;
		mwheelI.pos = pos;
		minDif = 250;

		clearTimeout(shortDelay);
		shortDelay = setTimeout(function(){
			minDif = 10;
		}, 200);
		clearTimeout(longDelay);
		longDelay = setTimeout(function(){
			minDif = 3;
		}, 1500);
		e = $.extend({}, e, {type: 'mwheelIntent'});
		return $.event.handle.call(this, e, d);
	}
}
</pre>
<p>Im Ergebnis kann der User also 200ms nachdem er das Mausrad bedient hat die Maus um 250 Pixel bewegen, ohne daß dies eine Änderung des durch das Mausrad bedienbaren Bereichs zur Folge hat. Außerdem ist der Bereich für 1.5 Sekunden von 3 auf 10 Pixel erhöht.</p>
<h2>Fazit</h2>
<p>Die Berücksichtigung von Mausradeingaben kann die Userexpierence und die Bedienbarkeit von Widgets steigern, aber auch gleichzeitig große Usability-Problem verursachen, wenn die Intention des Users nicht berücksichtigt wird. Mit ein bißchen JS kann die wahrscheinliche Intention des Nutzers berechnet werden. (<a href="http://plugins.jquery.com/project/mwheelIntent">zur mwheelIntent-Projekt-Seite</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protofunc.com/2009/12/29/mwheelintent-das-gebrauchstaugliche-mouswheel-event/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery: live-Methode / Braucht jQuery 1.4 eine neue API für Event Delegation?</title>
		<link>http://www.protofunc.com/2009/12/08/jquery-live-methode-braucht-jquery-14-eine-neue-api-fur-event-delegation/</link>
		<comments>http://www.protofunc.com/2009/12/08/jquery-live-methode-braucht-jquery-14-eine-neue-api-fur-event-delegation/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 20:12:58 +0000</pubDate>
		<dc:creator>alexander farkas</dc:creator>
				<category><![CDATA[deutsch]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.protofunc.com/?p=30</guid>
		<description><![CDATA[Jedes jQuery-Major-Release hat wesentliche Neuerungen/Verbesserungen gebracht. Bei jQuery 1.3 war es wohl die Einführung von Sizzle, die Umstellung von Browser-Sniffing auf Feature-Detection und die Einführung der live-Methode für Event Delegation.
Letztendlich habe ich die live-Methode in jQuery 1.3 so gut wie nie genutzt, da ich es für meine Usecases für ineffizient gehalten habe, das document-Objekt mit [...]]]></description>
			<content:encoded><![CDATA[<p>Jedes jQuery-Major-Release hat wesentliche Neuerungen/Verbesserungen gebracht. Bei jQuery 1.3 war es wohl die Einführung von Sizzle, die Umstellung von Browser-Sniffing auf Feature-Detection und die Einführung der live-Methode für Event Delegation.</p>
<p>Letztendlich habe ich die live-Methode in jQuery 1.3 so gut wie nie genutzt, da ich es für meine Usecases für ineffizient gehalten habe, das document-Objekt mit Eventlistener zu zuknallen. Eine präzisere Möglichkeit Event Delegation in jQuery 1.3 zu nutzen, war für mich immer die Nutzung der closest-Methode:</p>
<pre class="brush: jscript;">
$('#nav').bind('click', function(e){
	// Der zweite Parameter wird erst in jQuery 1.4 eingeführt!
	var anchor = $(e.target).closest('a', this);
	if(!anchor[0]){return;)
	// mach was mit anchor
});
</pre>
<h2>Das Problem mit der live-Methode</h2>
<p>Mit jQuery 1.4 wird Event Delegation und die Möglichkeiten der live-Methode stark erweitert. Zum einen werden Events unterstützt, die nicht bubbeln und zum anderen soll der Entwickler bestimmen können, an welches DOM-Objekt der Eventlistener hinzugefügt wird. Dies dürfte in jedem Fall dazu führen, daß die Methode häufiger eingesetzt wird. Gleichzeitig haben einige Leute in der Vergangenheit gefordert, die live-Mwthode entweder abzuändern oder zumindest eine neue Methode einzuführen. Dies geschah mit besonderer Rücksicht auf Performance und wurde &#8211; meiner Meinung nach &#8211; zurecht abgelehnt.</p>
<p>Das Problem ist jedoch, daß die live-Methode schwer zu erklären/dokumentieren ist, leicht zu Fehlern führen kann und den Entwickler dazu zwingt bereits beim Instantiieren eines jQuery-Objekts über die spätere Art der Event Delegation nachzudenken. Diese Grundproblematik läßt sich bereits bei jQuery 1.3 ausmachen und wird bei jQuery 1.4 noch komplizierter (aber nicht unbedingt schlimmer).</p>
<h2>Problem bei jQuery 1.3</h2>
<p>Laut jQuery-Dokumentation kann live u.a. nicht verwendet werden, wenn man beim Instanzieren den Context-Parameter nutzt bzw. wenn man Traversing-Methoden zwischenschaltet. Eine ältere jQuery Dokumentation hat hiervon ausdrücklich die Methode find als nicht funktionierende Traversing Methode ausgenommen. Letztendlich stimmt diese Behauptung in der Dokumentation nicht ganz. Eine Erklärung wann dies funktionieren kann und wann nicht, wäre jedoch einfach zu kompliziert. Hier eine kurze Erklärung</p>
<pre class="brush: jscript;">
// funktioniert in 1.3 nicht,
$('li', $('#nav')[0]).live('click'....
// ... da
// 1. der Eventlistener dem document-Objekt hinzugefügt wird
// 2. jQuery ausschließlich den 'li', aber nicht den '#nav' Selektor kennt

// funktioniert in 1.3,
$('li', $('#nav')).live('click'....
$('#nav').find('li').live('click'....
// ... da
// jQuery beide Selektor-Bestandteile kennt und diese zu '#nav li' zusammenfassen kann

// funktioniert in 1.3 nicht,
$('li, a', $('#nav')).live('click'....
// ... da jQuery beide Selektor-Bestandteile zu '#nav li, a' zusammenfaßt
</pre>
<h2>Eskalierung des Problems mit jQuery 1.4 (nightly-Stand)</h2>
<p>jQuery 1.4 ist noch nicht draußen, aber der derzeitige Stand kann über github eingesehen werden. Zudem existiert eine <a href="http://blog.jquery.com/2009/12/04/jquery-14-alpha-1-released/">öffentliche Alpha</a>, welche ich zum Testen herangezogen habe.</p>
<p>Mit dem derzeitigen Stand von jQuery 1.4a1 wird die oben beschriebene Ungenauigkeit zu einem großen Problem, denn die Verwendung des context-Parameters soll nicht nur ermöglicht werden, sondern wird zu einem elementaren Feature, da nun der context-Parameter bestimmen soll, an welchem Element der Eventhanlder gebunden werden soll. Das Problem hierbei ist jedoch eben die Tatsache, daß es eine Reihe von Bedingungen auftreten müssen, damit das ganze funktioniert.</p>
<pre class="brush: jscript;">
//Event wird in der Regel an nav-Element gebunden und funktioniert in der Regel wie gewünscht
$('li', $('#nav')[0]).live('click'....
// aber dann nicht, wenn $('#nav')[0] === undefined ist

//Event wird an document-body gebunden (Obwohl ein context-Parameter angegeben wurde, funktioniert aber ansonsten wie gewünscht.)
$('li', $('#nav')).live('click'....

//Funktioniert wie bei jQuery 1.3 nicht wie gewünscht
$('li, a', $('#nav')).live('click'....
</pre>
<p>Die Dokumentation müßte hier einerseits auf die Unterscheidung hinweisen, was alleine für sich bereits ziemlich verwirrend sein könnte und andererseits darauf, daß die 1. Zeile fehleranfällig ist. Kommt nämlich auf der gesamten Seite kein #nav-Element vor, ist $(&#8216;#nav&#8217;)[0] undefined, was dazu führt, daß erstens der Eventhandler zum document.body hinzugefügt und zweitens der Eventhandler bei jedem Click auf/in irgend ein li aufgerufen wird und damit nicht so funktioniert wie gewünscht.</p>
<p>Das gesamte Problem wird zusätzlich verschärft, wenn man einen Eventhandler mehreren Elementen hinzufügen möchte.</p>
<pre class="brush: jscript;">
//Event wird an das document.body gebunden und funktioniert wie gewünscht
$('div.teaser', $('div.teaser-wrapper')).live('click'...

//Schreibweise wird von jQuery nicht unterstützt, Event wird an document.body gebunden und jeder Click auf/in ein div.teaser löst Event aus
$('div.teaser', $('div.teaser-wrapper').get()).live('click'...
</pre>
<p>Funktionierender Code, der das neue Event Delegation-Feature von jQuery 1.4 nutzt und dabei sowohl klar, verständlich als auch robust ist, könnte beispielsweise wie folgt aussehen:</p>
<pre class="brush: jscript;">
$('#nav').each(function(){
	$('a', this).live('click' ...
});
//oder
$('div.teaser-wrapper').each(function(){
	$('div.teaser', this).live('click' ...
});
</pre>
<p>Letztendlich sind wir damit ziemlich nah an dem dran, was wir bereits in jQuery 1.3 schreiben können, um Event Delegation mit anderem context als document bzw. document.body zu nutzen, nämlich:</p>
<pre class="brush: jscript;">
$('#nav').bind('click', function(e){
	// Der zweite Parameter wird erst in jQuery 1.4 eingeführt!
	var anchor = $(e.target).closest('a', this);
	if(!anchor[0]){return;)
	// mach was mit anchor
});
</pre>
<p>Es ist ziemlich &#8220;jQuery-unlike&#8221; mehrere Zeilen-Code zu schreiben, um nur eine &#8220;einfache&#8221; Sache zu erreichen, aber genau das würde bei einer Beibehaltung der derzeitigen API passieren. Ganz abgesehen davon, daß die Dokumentation um weitere kompliziertere Erklärungen nicht umhin kommen würde.</p>
<p>Eine einfache Implementierung einer neuen jQuery-Event Delegation API könnte hierbei beispielsweise wie folgt aussehen.</p>
<pre class="brush: jscript;">
(function($){
	var dummy = $([]);

	$.each({addLive: 'live', removeLive: 'die'}, function(name, jMethod){
		$.fn[name] = function(sel){
			var args = (this[0]) ? Array.prototype.slice.call(arguments, 1) : [];
			return this.each(function(){
				dummy.selector = sel;
				dummy.context = this;
				$.fn[jMethod].apply(dummy, args);
			});
		};
	});
})(jQuery);
</pre>
<p>Die Nutzung würde hierbei wie folgt aussehen:</p>
<pre class="brush: jscript;">
function fn(){
	alert('F');
}
//bind live:
$('div.teaser-wrapper').addLive('div.teaser', 'click', fn);
// unbind live/die
$('div.teaser-wrapper').removeLive('div.teaser', 'click', fn);
</pre>
<h2>Fazit:</h2>
<p>jQuery 1.4 benötigt nicht unbedingt eine neue Methode für Event-Delegation. Die Verwendung des context-Parameters wird nun grundsätzlich ermöglicht und damit mögliche Fehler einer flaschen Benutzung minimiert. &#8220;Power User&#8221;, die jedoch Wert darauf legen, daß sie die volle Kontrolle darüber haben, welchem Element der Event-Listener genau hinzugefügt wird, würden sich jedoch stark über eine anders funktionierende Methode freuen.</p>
<p>Eine solche Methode wäre dann nicht nur einfacher zu erklären, sondern würde ebenfalls die Forderung nach einer performanteren (ohne Unnötiges Selektieren von Elementen, die man nicht braucht) berücksichtigen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protofunc.com/2009/12/08/jquery-live-methode-braucht-jquery-14-eine-neue-api-fur-event-delegation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Der große Screenreader Focus-Test</title>
		<link>http://www.protofunc.com/2009/10/11/der-grose-screenreader-focus-test/</link>
		<comments>http://www.protofunc.com/2009/10/11/der-grose-screenreader-focus-test/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 20:41:45 +0000</pubDate>
		<dc:creator>alexander farkas</dc:creator>
				<category><![CDATA[accessibility]]></category>
		<category><![CDATA[deutsch]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.protofunc.com/?p=29</guid>
		<description><![CDATA[Das Versetzen des Fokus, ist ein recht effizientes Mittel, um dynamische Änderungen im HTML Screenreader-Nutzern bekannt zu machen oder Probleme der Linearisierung beim Scripting zu umgehen (beispielsweise beim Anzeigen eines Dialogs bzw. einer Lightbox). Die Möglichkeit praktisch jedes beliebige Element zu fokusieren ist wohl einer der wichtigsten Bausteine für Wai-Aria. Das Schöne: Grundsätzlich sollte diese [...]]]></description>
			<content:encoded><![CDATA[<p>Das Versetzen des Fokus, ist ein recht effizientes Mittel, um dynamische Änderungen im HTML Screenreader-Nutzern bekannt zu machen oder Probleme der Linearisierung beim Scripting zu umgehen (beispielsweise beim Anzeigen eines Dialogs bzw. einer Lightbox). Die Möglichkeit praktisch jedes beliebige Element zu fokusieren ist wohl einer der wichtigsten Bausteine für Wai-Aria. Das Schöne: Grundsätzlich sollte diese Technik auch in nicht aria-fähigen Browser-/Screenreader-Kombinationen möglich sein.</p>
<p>Gleichzeitig gibt es jedoch Unterschiede zwischen Screenreadern in der Unterstützung der focus-Methode. Der generelle Support dieser Methode ist bereits beim wohl wichtigsten Screenreader Jaws je nach Version unterschiedlich. Hier zeigt sich, daß Jaws 10 einen großen Sprung nach vorn gemacht hat und praktisch gar keine Probleme macht, währenddem Jaws 8 bzw. Jaws 9 noch einige Probleme haben. Möchte man diese älteren Versionen unterstützen, sollte man wissen, was geht und was nicht.</p>
<h2>Zum Testaufbau</h2>
<p>Getestet wurde mit den Jaws Versionen 8, 9 und 10 sowie mit den Browsern IE8, IE7 sowie Firefox 3.5. Zusätzlich wurde im IE8 mit Cobra 8.1 und Webformator 2.4c sowie mit NVDA 0.6p3.2 im Firefox 3.5 getestet. Abschließend wurde nochmals mit der aktuellen Beta-Version von NVDA (NVDA 2009.1beta1) getestet. Im wesentlichen hat sich herausgestellt, daß sich IE7 nicht von IE8 und Jaws 8 nicht von Jaws 9 unterscheiden, so daß die Testergbenisse zusammengefaßt werden.</p>
<ul>
<li>Der Fokus sollte aufgrund eines Klicks auf einen Link, als Kontrollelement, verschoben werden</li>
<li>Jaws sollte die ganze Zeit über im normalen Modus arbeiten (Virtueller Cursor Modus war an, kein EINFÜGEN + Z)</li>
<li>Eine zusätzliche Verwendung von Aria-Attributen, welche den Screenreader in den Applikationsmodus versetzen könnte, war verboten</li>
<li>Der Buffer von Jaws wurde nicht manuell upgedatet (kein Einfügen + ESC)</li>
</ul>
<p>Der Test galt nur als bestanden, wenn der Screenreader den Inhalt des fokusierten Bereich vorgelesen hat und sowohl der virtuelle Cursor als auch der &#8220;physikalische&#8221; Fokus richtig verschoben war. Der User also sowohl mit den Pfeiltasten als auch mit der Tab-Taste vom neu fokusierten Element aus arbeiten kann.</p>
<h2>Welche Elemente können fokusiert werden</h2>
<p>Normalerweise können &#8211; laut HTML 4 Spezifikation &#8211; nur Interaktionselemente, welche nicht versteckt oder deaktiviert sind, fokusiert werden (also Links, Buttons, Eingabefelder etc.). Mit dem tabindex-Wert -1 können diese für den User unfkousierbar gemacht werden, währenddem sie weiterhin durch Javascript fokusiert werden können. Alle getestet Screenreader-/Browser-Kombinationen konnten ohne Probleme diese Elemente im Test fokusieren.</p>
<p>Mit Hilfe des tabindex-Attributs sollen ebenfalls alle anderen Elemente fokusierbar gemacht werden können. Hat das tabindex-Attribut den Wert 0 kann dieses Element sowohl durch den Nutzer als auch durch Javascript fokusiert werden. In allen getesteten Screenreadern konnten solche Elemente durch den User fokusiert werden. In Jaws 8/9 mit Internet Explorer konnten allerdings Elemente, die normalerweise nicht foksuierbar sind, nicht mit der Javascript-Methode focus fokusiert werden (Beispiel: span[tabindex=0], span[tabindex=-1]). Als Ausnahme dieser Regel stellten sich Überschriften heraus. Befand sich das zu fokusierende Element in einer Überschrfit bzw. war es eine Überschrift, konnte dieses auch in Jaws 8/9 fokusiert werden.</p>
<p>Cobra 8.1 laß anchor-Elemente ohne href-Attribut manchmal als Links vor, was irritierend sein dürfte. Befand sich direkt über dem fokusierten Element eine Überschrift und das fokusierte Element war selbst keine Überschrift, wurde diese zusätzlich in Jaws als auch in Cobra vorgelesen.</p>
<p>Regel: Fokusiere nur Elemente, die Interaktionselemente sind oder Überschriften mit tabindex bzw. Elemente mit tabindex, die in Überschriften plaziert wurden. Mit Rücksicht auf Cobra sollten keine anchor-Elemente ohne href-Attribut fokusiert werden.</p>
<p>Nachfolgend der <a href="http://www.protofunc.com/scripts/jquery/focustest/simplefocusable.html">Testcase für das einfache Fokusieren</a>.</p>
<h2>Fokusieren von vor kurzem noch versteckten bzw. gerade erst erschaffenen Elementen</h2>
<p>Um zwischen den Screenreadern Waffengleichheit herzustellen, wurde der Webformator so eingestellt, daß er nur wirklich sichtbare Elemente anzeigt.</p>
<p>Das Fokusieren von gerade noch versteckten Elementen bzw. Elementen, die erst aufgrund einer User-Aktion ins DOM eingefügt werden (beispielsweise Click -> Ajax -> innerHTML -> focus), gehört wohl zu den problematischsten aller Möglichkeiten. Im wesentlichen haben sich aber alle Screenreader, außer Jaws 8/9, recht gut geschlagen.</p>
<p>Damit Screenreader solche Elemente fokusieren können, müssen sie ihre Ausgabe aktualisieren, um das zu fokusierende Element zu finden. Grundsätzlich sollte die focus-Methode hierzu mit der setTimeout-Methode verknüpft werden. Dies ist weniger ein Workaround, bei dem abgewartet wird, bis die Ausgabe durch den Screenreader aktualisiert wird, sondern ein technisches Erfordernis, welches mit der <a href="http://ejohn.org/blog/how-javascript-timers-work/">Arbeitsweise von Events im Browser</a> zu tun hat, welche u.a. Jaws 10 zum Updaten seines Buffers heranzieht. Der Testcase umfaßte hierbei mehrere Delays zum Testen (0ms, 180ms, 400ms). Letztendlich gab es hierbei jedoch in der Regel keine Unterschiede zwischen den delays. Wichtig war nur das die focus-Methode, welche im selben Thread arbeitet wie das Sichtbarmachen/Einfügen selbst, durch die setTimeout-Methode &#8220;gequeued&#8221; wird.</p>
<p>Jaws 10 und Cobra haben hierbei sämtliche Tests ohne Probleme absolviert.</p>
<p>NVDA sowie Jaws 8/9 hatten dagegen gewisse Probleme. Befand sich das zu fokusierende Elemente über dem aktuell fokusierten Kontrollelement, wurde durch Jaws 8/9 sowie NVDA 0.6p3.2 der Fokus zwar verschoben, jedoch der fokusierte Text nie gesprochen.</p>
<p>Die aktuelle Beta-Version von NVDA sprach zwar alle fokusierten Texte, also auch die, welche sich vor dem Kontrollelement befanden, hatte jedoch bei allen Testfällen das Problem, daß sowohl Tab-Taste als auch Pfeiltasten, nach der Fokusierung immer noch vom Kontrolelement aus starteten. Ein also Weiterarbeiten vom fokusierten Bereich aus nicht möglich war. Hierbei handelt es sich um einen Regressionsbug, der nicht in der 0.6p3.2-Version auftritt. Ich hoffe, daß dieser Bug bis zur Final behoben sein wird.</p>
<p>Jaws 8/9 hatte noch das zusätzliche Problem dahingehend, daß der fokusierte Text auch wenn er nach dem Kontrollelement kam, manchmal nicht gesprochen und/oder der Cursor manchmal nicht richtig verschoben wurde. Dies hatte letztendlich mit zwei Dingen zu tun:</p>
<p>Zum einen ist es von der Bedienung des Screenreaders abhängig, ob er seine Ausgabe rechtzeitig updatet. Wurde der virtuelle Cursor, beispielsweise mit den Pfeiltasten, über den Link gebracht und dann mit der Enter-Taste der Link ausgelöst, klappte das Fokusieren in der Regel. Wurde dagegen der &#8220;richtige&#8221; Fokus mit der Tab-Taste auf das Kontrollelement versetzt und dann mit der Enter-Taste ausgelöst, wurde die Ausgabe in der Regel nicht richtig upgedatet und es kam mit allen Delays zu Problemen.</p>
<p>Zum anderen Griff im Widerspruch zu dem oben gesagten ein Delay von 0 bzw. 50 nicht immer (aber in etwa 90% aller Fälle). Sobald das Delay jedoch über 100ms betrug und das Kontrollelement mit dem virtuellen Cursor ausgewählt wurde, wurden auf allen bisher getesteten Rechnern mit unterschiedlicher CPU (1 Single Core sowie 2 Core DUO), unterschiedlicher CPU Auslastung (normal bis 100%) sowie unterschiedlicher Sprachgeschwindigkeit die fokusierten Texte immer gesprochen und richtig versetzt.</p>
<p>Regel: Will man ältere Jaws-Versionen unterstützen (und das sollte man), sollte man das Fokusieren von gerade noch versteckten bzw. gerade erst erstellten Elementen bleiben lassen und andere Techniken nutzen.</p>
<p>Nachfolgend der <a href="http://www.protofunc.com/scripts/jquery/focustest/hiddenfocusable.html">Testcase für das Fokusieren von gerade sichtbar gemachten Elementen</a>.</p>
<h2>Inhalt Umschreiben und dann Fokusieren</h2>
<p>Als eine wirkungsvolle Alternative für das Fokusieren von gerade sichtbar gemachten Elementen, bietet sich das Umtexten von bereits vorhandenen sichtbaren Elementen und das nachfolgende fokusieren dieser an. Dirk Ginader hatte diese Technik in seinem <a href="http://blog.ginader.de/archives/2009/02/07/jQuery-Accessible-Tabs-Wie-man-Tabs-WIRKLICH-zugaenglich-macht.php">barrierefreien Tab-Beispiel</a> gezeigt. Diese Technik bietet sich aber nicht nur für Tabs an, sondern auch für viele andere Dinge an.</p>
<p>Die Testfälle absolvierten letztendlich (fast) alle Screenreader. Lediglich wieder Jaws 8 und Jaws 9 hatten mit einem unwahrscheinlichen Testfall Schwierigkeiten. Befand sich innerhalb des umgeschriebenen Elements kein initialer Text verhielt sich Jaws 8/9 ähnlich begriffsstutzig wie bei gerade erst sichtbar gemachten Elementen. Da Jaws 8 und 9 allerdings gleichzeitig nur Interaktionselemente sowie Überschrfiten fokusieren können, dürfte man sowieso selten mit einem solchen Element leeren Inhalts arbeiten wollen.</p>
<p>Regel: Elemente, die zum Umschreiben und Fokusieren gedacht sind, sollten nicht mit leerem Inhalt &#8220;starten&#8221;.</p>
<p>Nachfolgend der <a href="http://www.protofunc.com/scripts/jquery/focustest/rewritefocus.html">Testcase für das Fokusieren von gerade &#8220;umgeschribenen&#8221; Elementen</a>.</p>
<h2>Fokusieren von gerade sichtbar gemachten/eingefügten Elementen Teil 2</h2>
<p>Um dennoch die Möglichkeit zu haben gerade erst erstellte/sichtbar gemachte Elemente zu fokusieren, sind Workarounds denkbar. Ich habe hierzu einen <a href="http://www.protofunc.com/scripts/jquery/focustest/hiddenfocusable2.html">Testcase mit abgewandelter setFocus-Methode</a> zur Verfügung gestellt, welcher nach ersten Tests recht zuverlässig in Jaws 8/9 funktioniert und in anderen Screenreadern keine Probleme auslöst.</p>
<p>Regel: Wenn man Inhalte nicht umschreiben kann, dann &#8211; und nur dann &#8211; das modifizierte setFocus-Script ausprobieren.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protofunc.com/2009/10/11/der-grose-screenreader-focus-test/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Wai-Aria Widget-Entwicklung mit Accessibility Probe/Inspect am Beispiel einer custom Select-Drop-Down-Box</title>
		<link>http://www.protofunc.com/2009/09/23/wai-aria-widget-entwicklung-mit-accessibility-probeinspect-am-beispiel-einer-custom-select-drop-down-box/</link>
		<comments>http://www.protofunc.com/2009/09/23/wai-aria-widget-entwicklung-mit-accessibility-probeinspect-am-beispiel-einer-custom-select-drop-down-box/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 09:11:05 +0000</pubDate>
		<dc:creator>alexander farkas</dc:creator>
				<category><![CDATA[accessibility]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.protofunc.com/?p=28</guid>
		<description><![CDATA[Einleitung
Die Entwicklung von Aria-Widgets ist letztendlich keine triviale Sache. Zum einen müssen alle für das Widget wichtigen Aria-Attribute vorhanden sein, die Verschachtelung und letztendlich auch das &#8211; durch den Entwickler zu implementierende &#8211; Verhalten stimmen.  Fehler in der HTML-Struktur oder dem Verhalten können häufig größeren Schaden anrichten als helfen. Bei der Entwicklung von zugänglichen [...]]]></description>
			<content:encoded><![CDATA[<h2>Einleitung</h2>
<p>Die Entwicklung von Aria-Widgets ist letztendlich keine triviale Sache. Zum einen müssen alle für das Widget wichtigen Aria-Attribute vorhanden sein, die Verschachtelung und letztendlich auch das &#8211; durch den Entwickler zu implementierende &#8211; Verhalten stimmen.  Fehler in der HTML-Struktur oder dem Verhalten können häufig größeren Schaden anrichten als helfen. Bei der Entwicklung von zugänglichen Javascript-Komponenten erhält daher das Testen mit verschiedenen Screenreader-/Browser-Kombinationen eine hohe Bedeutung. Dieses Tutorial soll helfen zu zeigen, wie einfach man &#8220;bessere&#8221; Wai-Aria-Widgets schreibt bzw. wie man bereits vorhandene Widgets beurteilen kann, um den Entwickler auf Fehler aufmerksam zu machen.</p>
<p>Dies möchte ich am Beispiel einer normalen Ausklappliste demonstrieren, doch vorab hier eine <a href="/scripts/jquery/select/">Demo sowie ein Screencast</a>, welches das fertige Aria-Widget mit verschiedenen Screenreader/Browser-Kombinationen zeigt.</p>
<h2>Gute Resourcen</h2>
<p>Die zentrale Anlaufstelle für gute Inhalte zum Thema WAI-Aria stellt <a href="http://wiki.codetalks.org/wiki/index.php/Main_Page">Codetalks von Mozilla</a> zur Verfügung. Dort lassen sich zahlreiche Aria-Beispiele/Test Cases, Artikel, FAQs, Tutorial, Blogs, Tools rund um das Thema Aria finden.</p>
<p>Einiges sei hier extra erwähnt.</p>
<ul>
<li> Die entscheidenden Passagen des <a href="http://www.w3.org/WAI/PF/aria-practices/">Aria Best Practices Dokuments</a> sollten immer vor der Entwicklung eines Widgets gelesen werden. Das Dokument enthält sowohl allgemeine Informationen (z.B. Tastaturbenutzung/Fokus-Management) sowie konkrete Informationen zu entsprechenden Widgets (in unserem Fall der <a href="http://www.w3.org/WAI/PF/aria-practices/#combobox">combobox</a>).</li>
<li> Scripte sollten immer mit mehr als einem Screenreader und mehr als einem Browser getestet werden. Todd Kloots hat hierzu im YUI-Blog einige Informationen zum <a href="http://yuiblog.com/blog/2008/12/30/configuring-screen-readers/">Installieren und Konfigurieren von Screenreadern für Entwickler</a> zusammengestellt. Marco Zehe gibt weitere Informationen zum <a href="http://www.marcozehe.de/articles/how-to-use-nvda-and-firefox-to-test-your-web-pages-for-accessibility/">Testen mit NVDA</a>.</li>
<li> Gute Tools machen uns das Entwicklen deutlich einfacher. Neben Tools wie Firebug/Dragonfly sind dies für die Aria-Entwicklung insbesondere die <a href="https://addons.mozilla.org/en-US/firefox/addon/5809">Firefox Accessibility Extension</a> sowie eines der im Titel dieses Tutroials genannten Accessibility-Inspect Tools (<a href="http://www.microsoft.com/downloads/details.aspx?familyid=3755582A-A707-460A-BF21-1373316E13F0">Inspect</a> bzw. <a href="http://www.eclipse.org/actf/downloads/tools/accprobe/index.php">Accessibility Probe</a>).</li>
<li>Eine mögliche Anlaufstelle für Fragen sowie Diskussionen über eigene Lösungen/Ansätze stellt die <a href="http://groups.google.com/group/free-aria">Free ARIA Community</a> dar.</li>
</ul>
<h2>Die Accessibility-Infomationen des select-Elements (im Firefox)</h2>
<p>Die Aria-Rolle combobox beschreibt sowohl das Widget Ausklappliste (Dropdown-Liste), bei dem der Benutzer zwischen vorgegeben Werten wählen kann, als auch das Widget &#8220;kombiniertes Eingabefeld&#8221;, bei dem der Nutzer zusätzlich freie Texteingaben machen kann. Wir werden in diesem Tutorial das Inspect-Tool von Microsoft dafür nutzen, um die richtige HTML-Struktur inklusive der Aria-Attrbiute für eine einfache Ausklappliste zu ermitteln und zu testen.</p>
<p>Wenn wir ein Select-Element mit folgender HTML-Struktur schreiben,</p>
<pre class="brush: xml;">
&lt;label for=&quot;select-element&quot; id=&quot;label&quot;&gt;Bezeichner&lt;/label&gt;
&lt;select id=&quot;select-element&quot;&gt;
	&lt;option&gt;Option A&lt;/option&gt;
	&lt;option&gt;Option B&lt;/option&gt;
&lt;/select&gt;
</pre>
<p>&#8230; erhalten wir folgende Accessibility-Informationen:</p>
<p>Das select-Element besitzt einen Namen (das label), einen aktuellen Wert, eine Rolle (Kombinationsfeld), verschiedene default-Zustände und eine unsichtbare Liste, welche ebenfalls mit dem label-Element verbunden ist.</p>
<p>Sofern wir die unsichtbare Liste weglassen, erreichen wir mit folgender HTML-Struktur die Weitergabe ähnlicher Accessibility-Informationen im Firefox:</p>
<pre class="brush: xml;">
&lt;span id=&quot;label&quot;&gt;Bezeichner&lt;/span&gt;
&lt;div role=&quot;combobox&quot; aria-valuetext=&quot;Option A&quot; aria-labelledby=&quot;label&quot; tabindex=&quot;0&quot;&gt;
	Option A
&lt;/div&gt;
</pre>
<p>Die obige HTML-Struktur berücksichtigt jedoch nicht die fatale Kleinigkeit, daß der Internet Explorer 8 die valuetext-Eigenschaft nicht unterstützt. Letztendlich kann man Microsoft zumindest bei der combobox keinen Fehler vorwerfen, denn die <a href="http://www.w3.org/TR/wai-aria/#combobox">Aria-Spezifikation für comboboxen</a> sieht dies selbst nicht vor. Bei der Spezifikation hatte man anscheinend vor allem das Widget kombiniertes Eingabefeld im Kopf und die Realisierung der einfachen Drop-Down-Liste vergessen (reine Behauptung/Vermutung). Das Aria Best Practices Dokument geht dann zwar auf Ausklapplisten ein (verkürzte HTML-Struktur: [role=combobox][tabindex=-1] &gt; [role=textbox][aria-readonly=true][tabindex=0]), aber dies würde zu einer HTML-Struktur führen, die in Screenreadern nicht funktioniert.</p>
<h2>Mit Bugs gegen Bugs</h2>
<p>Ein Problem bei der Entwicklung von Aria-Widgets ist die Tatsache, daß semantische Überreste von Elementen übrig bleiben, wenn man die Rolle mit Aria ändert. Ein typisches Beispiel hierfür ist ein Anchor-Element mit einem href-Attribut.</p>
<pre class="brush: xml;">
&lt;a href=&quot;#bla&quot; role=&quot;button&quot;&gt;Button-Text&lt;/a&gt;
</pre>
<p>Bei dieser Grundstruktur wird zwar aus einem Link ein Schalter, aber dieser Schalter besitzt neben dem Namen &#8220;Button-Text&#8221; noch zusätzlich den Wert der href-DOM-Eigenschaft als &#8220;Zugänglichkeitswert&#8221; (nicht zu Verwechseln mit dem Wert des href-Attributs). Aus diesem Grund sollte man, wenn man einen Link mit einer anderen Rolle belegt, das href-Attribut entfernen. Dies führt gleichzeitig dazu, daß</p>
<ol>
<li>der Link ohne tabindex-Attribut nicht mehr fokusierbar ist</li>
<li>die Pseudoklasse :focus nicht in allen Browsern funktioniert (im IE6 funktioniert auch :hover nicht mehr)</li>
<li>ein click-Event auf dem Link kein geräteunabhängiges Event mehr darstellt</li>
</ol>
<p>Nun ist für uns die href-DOM-Eigenschaft nicht wirklich brauchbar, da wir diesen Wert nicht in der Hand haben. Das selbe Problem besteht jedoch ebenfalls bei Texteingabefeldern und läßt sich zur Lösung unseres Problems mißbrauchen.</p>
<p>Folgende HTML-Struktur ergibt sowohl im Firefox als auch im Internet Explorer die gewünschten Zugänglichkeitsinformationen:</p>
<pre class="brush: xml;">
&lt;span id=&quot;label&quot;&gt;Bezeichner&lt;/span&gt;
&lt;input role=&quot;combobox&quot; value=&quot;Option A&quot; aria-labelledby=&quot;label&quot; tabindex=&quot;0&quot; /&gt;
</pre>
<h2>Die Ausklappliste selbst</h2>
<p>Zusammen mit der Ausklappliste würde die HTML-Struktur wie folgt aussehen:</p>
<pre class="brush: xml;">
&lt;span id=&quot;label&quot;&gt;Bezeichner&lt;/span&gt;
&lt;input role=&quot;combobox&quot; value=&quot;Option A&quot; aria-labelledby=&quot;label&quot; tabindex=&quot;0&quot; /&gt;
&lt;!-- weiteres HTML dazwischen | listbox wird ans Ende des Dokuments hinzugefügt --&gt;
&lt;ul role=&quot;listbox&quot; aria-labelledby=&quot;label&quot;&gt;
	&lt;li role=&quot;option&quot; tabindex=&quot;-1&quot;&gt;Option A&lt;/li&gt;
	&lt;li role=&quot;option&quot; tabindex=&quot;-1&quot;&gt;Option B&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>Ändert der User mit der Maus oder mit den hoch/runter-Pfeiltasten die Optionen, wird dies über das zusätzliche Wai-Aria-Attribut activedescendant deutlich gemacht:</p>
<pre class="brush: xml;">
&lt;span id=&quot;label&quot;&gt;Bezeichner&lt;/span&gt;
&lt;input role=&quot;combobox&quot; value=&quot;Option B&quot; aria-labelledby=&quot;label&quot; aria-activedescendant=&quot;option-2&quot; tabindex=&quot;0&quot; /&gt;
&lt;ul role=&quot;listbox&quot; aria-labelledby=&quot;label&quot;&gt;
	&lt;li role=&quot;option&quot; id=&quot;option-1&quot; tabindex=&quot;-1&quot;&gt;Option A&lt;/li&gt;
	&lt;li role=&quot;option&quot; id=&quot;option-2&quot; tabindex=&quot;-1&quot;&gt;Option B&lt;/li&gt;
&lt;/ul&gt;
</pre>
<h2>Focus-Management: activedescendant vs. tabindex + focus</h2>
<p>Grundsätzlich sollte man, statt der activedesendant-Methode, den Fokus mit tabindex und der focus-Methode ändern. Die focus-Methode funktioniert in recht vielen Browser-/Screenreader-Kombinationen, so daß Widgets, welche den focus auf diese Weise managen, selbst in Screenreader/Browser-Kombinationen funktionieren können, die kein Wai-Aria unterstüzten.</p>
<p>In unserem Fall, ist dieser Weg allerdings wenig sinnvoll, da wir die Liste ans Ende unseres Dokuments hinzufügen und dadurch aus der logischen Tabreihenfolge nehmen. Dem aufmerksamen Beobachter wird außerdem auffallen, daß wir den einzelnen Optionen dennoch ein tabindex-Attribut gegeben haben, obwohl wir die activedescendant-Methode nutzen und das Aria Best Practices Dokument in diesem Fall ein tabindex-Attribut für unnötig hält. Dies hat den Hintergrund, daß das tabindex-Attribut jedes Element nicht nur fokusierbar macht, sondern auch die Eigenschaft der Fokusierbarkeit (Markierbarkeit) an die jeweilige Zugänglichkeitsschnittstelle weiterleitet (Die Rolle option tut dies, wie fast alle Rollen, nicht implizit!). Fehlt dieses Attribut wird diese nicht weitergeleitet, was in einigen Screenreadern negative Folgen haben kann.</p>
<p>Wird die Liste reduziert, ist dieses Attribut wieder restlos zu entfernen.</p>
<p>Obgleich die Aria-Spezifikation noch weitere notwenige Aria-Attribute vorsieht (aria-expanded an der listbox) und weitere sinnvoll erscheinen (aria-checked an der jeweiligen Option, aria-selected=true|false an den Optionen), ist die oben gezeigte Aria-Struktur alles was wir für eine gut funktionierende Ausklappliste brauchen.</p>
<h2>Endgültige HTML-Struktur</h2>
<p>Mit dem Texteingabefeld als Workaround haben wir uns ein zusätzliches Problem geschaffen. Wird dieses fokusiert erscheint in der Regel ein Curosr und der Nutzer kann Text frei eingeben. Um dieses Verhalten rückgängig zu machen, müßen wir sowohl durch HTML-Struktur als auch unser Script einige Dinge berücksichtigen. Nachfolgend eine HTML-Struktur, welches einen Teil des ungewünschten Verhaltens rückgängig macht. Den Rest erledigen wir in unserem Script.</p>
<pre class="brush: xml;">
&lt;span id=&quot;label&quot;&gt;Bezeichner&lt;/span&gt;
&lt;div class=&quot;select&quot; tabindex=&quot;-1&quot;&gt;
	&lt;input role=&quot;combobox&quot; value=&quot;Option A&quot; aria-valuetext=&quot;Option A&quot; readonly=&quot;readonly&quot; aria-readonly=&quot;false&quot; aria-labelledby=&quot;label&quot; tabindex=&quot;0&quot; /&gt;
&lt;/div&gt;
&lt;ul role=&quot;listbox&quot; aria-labelledby=&quot;label&quot; id=&quot;datalist&quot;&gt;
	&lt;li role=&quot;option&quot; id=&quot;option-1&quot; tabindex=&quot;-1&quot;&gt;Option A&lt;/li&gt;
	&lt;li role=&quot;option&quot; id=&quot;option-2&quot; tabindex=&quot;-1&quot;&gt;Option B&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>Außerdem wollen wir die native Selectbox</p>
<ol>
<li>gegen eine schön stylbare/animierbare Selectbox tauschen</li>
<li>in ihren Zugänglichkeitsinformationen nicht nur funktional, sondern möglichst originalgetreu nachbauen</li>
</ol>
<p>und da brauchen wir bestimmt noch ein bißchen mehr HTML, so daß wir bei folgender Struktur landen:</p>
<pre class="brush: xml;">
&lt;span id=&quot;label&quot;&gt;Bezeichner&lt;/span&gt;
&lt;div class=&quot;select&quot; tabindex=&quot;-1&quot;&gt;
	&lt;input role=&quot;combobox&quot; value=&quot;Option A&quot; aria-valuetext=&quot;Option A&quot; readonly=&quot;readonly&quot; aria-readonly=&quot;false&quot; aria-expanded=&quot;false&quot; aria-labelledby=&quot;label&quot; tabindex=&quot;0&quot; /&gt;
&lt;/div&gt;
&lt;div role=&quot;listbox&quot; aria-labelledby=&quot;label&quot; id=&quot;datalist&quot;&gt;
	&lt;div role=&quot;presentation&quot;&gt;
		&lt;ul role=&quot;presentation&quot;&gt;
			&lt;li role=&quot;option&quot; id=&quot;option-1&quot; tabindex=&quot;-1&quot; aria-selected=&quot;true&quot;&gt;&lt;span role=&quot;presentation&quot;&gt;Option A&lt;/span&gt;&lt;/li&gt;
			&lt;li role=&quot;option&quot; id=&quot;option-2&quot; tabindex=&quot;-1&quot; aria-selected=&quot;false&quot;&gt;&lt;span role=&quot;presentation&quot;&gt;Option B&lt;/span&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/div&gt;
&lt;/div&gt;
</pre>
<h2>Wann ist die Liste ausgeklappt/sichtbar?</h2>
<p>Grundsätzlich klappt eine Auswahllliste für den User sichtbar erst bei gedrückter alt-Taste auf. Bei normaler Tastaturnutzung sieht es dagegen so aus, als würde sich lediglich der Wert des Select-Elements ändern. Wie ein Test mit dem Inspect-Tool zeigt, täuscht dieser Eindruck. Sobald der Wert mit den Pfeiltasten geändert wird, befindet sich der User automatisch auf der jeweiligen Option. Damit dies klappt, muß die Liste sichtbat gemacht (display: block; visibility: visible;) und das activedescendant-Attribut gesetzt werden. Es bleibt dem Autoren überlassen, ob er die Liste zu diesem Zeitpunkt außerhalb des Viewports plaziert oder nicht (In meiner Demo habe ich hierauf verzichtet).</p>
<h2>Das Setzen des activedescendant-Attributs</h2>
<p>Das activedescendant-Attribut sollte, ebenso wie das Setzen des Fokus mit der Fokus-Methode, immer mit einem timeout geschehen (Ein delay von 0 ms reicht). Wird das activedescendant-Attribut ohne delay auf ein Element gesetzt, welches zuvor noch versteckt war, kann der Screenreader dieses Element nicht finden und liest nichts vor. (Dies gilt nur für (neue) DOM-Elemente, nicht für die Änderung von Attributen oder Textknoten.)</p>
<h2>Fazit</h2>
<p>Es gibt viele Dinge, welche die Aria-Entwicklung erschweren: Browser-Bugs, Screenreader-Bugs, Merkwürdigkeiten in den Spezifikationen und letztendlich mangelndes Know-How. Geeignete Tools können uns helfen, diese Probleme schneller in den Griff zu kriegen. Ein Testen mit Screenreadern muß die Entwicklung begleiten.</p>
<p>Eine abschließende Frage an alle Entwickler, die mich immer wieder beschäftigt: Mit welchen Screenreader-/Browser-Kombinationen (inkl. Version) testet ihr bzw. bei welchen sollte &#8211; Eurer Meinung nach &#8211; die Funktionsfähigkeit sichergestellt werden (und sagt jetzt bitte nicht bei allen)?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protofunc.com/2009/09/23/wai-aria-widget-entwicklung-mit-accessibility-probeinspect-am-beispiel-einer-custom-select-drop-down-box/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Meinung zu HTML5: Semantik noch Flop, progressive enhancement Top</title>
		<link>http://www.protofunc.com/2009/08/16/meinung-zu-html5/</link>
		<comments>http://www.protofunc.com/2009/08/16/meinung-zu-html5/#comments</comments>
		<pubDate>Sun, 16 Aug 2009 18:44:50 +0000</pubDate>
		<dc:creator>alexander farkas</dc:creator>
				<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[deutsch]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.protofunc.com/?p=27</guid>
		<description><![CDATA[Ich bin ein großer Freund von HTML5. Allerdings kann ich nicht nachvollziehen, in welcher Form einige &#8211; bereits heute &#8211; HTML5 nutzen wollen bzw. zu nutzen empfehlen. Die tollen HTML5-Elemente (nav, aside, header, footer..), die wir mit dreckigen Tricks nutzen könnten, bringen nichts. Kein Browser, kein Screenreader und auch keine ernstzunehmende Suchmaschine unterstützen die Semantik [...]]]></description>
			<content:encoded><![CDATA[<p>Ich bin ein großer Freund von HTML5. Allerdings kann ich nicht nachvollziehen, in welcher Form einige &#8211; bereits heute &#8211; HTML5 nutzen wollen bzw. zu nutzen empfehlen. Die tollen HTML5-Elemente (nav, aside, header, footer..), die wir mit <a href="http://html5doctor.com/how-to-get-html5-working-in-ie-and-firefox-2/">dreckigen Tricks</a> nutzen könnten, bringen nichts. Kein Browser, kein Screenreader und auch keine ernstzunehmende Suchmaschine unterstützen die Semantik der neuen Tags, gleichzeitig bereiten Sie in allen Versionen des Internet Explorer sowie im Firefox 2 <a href="http://www.protofunc.com/scripts/jquery/section/">erhebliche Probleme und machen einiges kaputt</a>.</p>
<p>Auf der anderen Seite gibt es die <a href="http://www.vorsprungdurchwebstandards.de/theory/7-gruende-wai-aria-landmarks-sofort-einzusetzen/">schönen WAI-Aria-Landmarks</a>. Sie sind für eine zusätzliche Semantik definitiv der bessere Weg, weil sie im Gegensatz zu den oben genannten HTML 5 Element einfach funktionieren, helfen und nichts kaputt machen.</p>
<p>Andere Elemente wie figure und legend können teilweise durch aria-labelledby/aria-describedby substituiert werden.</p>
<p>Dies ist kein Widerspruch zu HTML 5. Im Gegenteil der HTML 5 Validator validiert inzwischen nicht nur Teile von Wai-Aria, sondern eben auch die Aria-Landmarks.</p>
<p>Neben den problemlos verwendbaren Aria-Attributen, gibt es in HTML5 viele schöne neue Sachen zu entdecken.</p>
<ul>
<li>Man kann sich endlich den doctype merken.</li>
<li>Das canvas-Element wird von allen modernen Browsern unterstützt und kann mit <a href="http://code.google.com/p/explorercanvas/">excanvas</a> auch im Internet Explorer zum Laufen gebracht werden (allerdings mit deutlich geringerer Performance).</li>
<li>Attribute wie autocomplete sind endlich Bestandteil von HTML 5. Ohne dieses Attribut sind mit Javascript erstellte Auto-Suggest-Listen für Eingabefelder unmöglich.</li>
<li>Es gibt neue, <a href="http://html5doctor.com/block-level-links-in-html-5/">befreiende Verschachtelungsregeln</a>.</li>
<li>Best practices wie beispielsweise document.documentElement.className += &#8216;js-on&#8217;; erzeugen endlich validen Code.</li>
</ul>
<p>Vor allem jedoch bietet HTML 5 &#8211; insbesondere bei Formularelementen – semantische Extras, die Javascript-Entwickler, gleichgültig von der derzeitigen Unterstützung im Browser, dringend benötigen, um eleganten, unobtrusiven Code schreiben zu können.</p>
<h2>Wie zusätzliche semantische HTML5-Attribute beim Aufbau von Javascript helfen</h2>
<p>Man stelle sich vor, man möchte einen Slider mit numerischen Werten realisieren. Dieser Slider soll jeweils einen vom Backend vorgegeben Startwert, Mindestwert und Höchstwert kennen. Als Javascript-Fallback soll ein einfaches Texteingabefeld dienen.</p>
<p>Während HTML 4 sowie XHTML 1.0  lediglich ein Attribut für den Startwert bieten, hilft uns HTML 5 ebenso beim Mindest- und Höchstwert unseres unobtrusiv zu erstellenden Sliders.</p>
<pre class="brush: xml;">
&lt;input type=“number“ value=“3“ min=“1“ max=“10“ /&gt;
&lt;!-- oder in Schritten --&gt;
&lt;input type=“number“ value=“3“ min=“1“ max=“10“ step=&quot;1&quot; /&gt;
&lt;!-- oder gleich als 'slider' --&gt;
&lt;input type=“range“ value=“3“ min=“1“ max=“10“ /&gt;
</pre>
<h2>HTML 5 und progressive enhacement</h2>
<p>HTML 5 bietet einige interessante Features, welche bereits heute mit Hilfe von Javascript  implementiert werden können.</p>
<p>Das oben beschriebene canvas-Element ist ein Beispiel hierfür, ein weiteres sind die zahlreichen Erweiterungen für Formularelemente, welche in Teilen bereits von Browsern implementiert wurden.</p>
<p>Die HTML 5 – Attribute liefern hierbei die semantische Grundlage für die Aktivierung und Konfiguierung des Javascripts.</p>
<p>Vor der Implementierung mit Javascript sollte man grundsätzlich testen, ob das Feature nicht bereits Teil des Browsers ist. Da die neuen HTML-Attribute in der Regel mit einem DOM-Interface korrelieren, ist dieser Test kinderleicht. Hier einige Beispiele mit jQuery:</p>
<pre class="brush: jscript;">
(function($){

	var form = $('&lt;form&gt;&lt;fieldset&gt;&lt;textarea /&gt;&lt;/fieldset&gt;&lt;/form&gt;');

	$.extend($.support, {
		//wird die Constrain Validation unterstützt?
		checkValidity: !!(form[0].checkValidity),
		// wird das maxlength-Attribut am textarea-Element unterstützt?
		textareaMaxlength: !!( $('textarea', form)[0].maxLength !== undefined || $('textarea', form)[0].maxlength !== undefined)
	});

})(jQuery);
</pre>
<h2>Eine Beispielimplementierung für das placeholder-Attribut</h2>
<p>Das <a href="http://dev.w3.org/html5/spec/Overview.html#the-placeholder-attribute">placeholder-Attribut </a>bietet ein Formularfeature, welches Frontend-Entwickler tagtäglich bereits heute mit Javascript in Webseiten nutzen; nämlich das Entfernen von vorbelegten Werten in Eingabefeldern. Hierbei ist das Standardverhalten wie folgt definiert: Der Placeholder stellt einen kurzen Hinweistext dar, welcher dem User als vorläufiger Wert im Eingabefeld angezeigt wird, solange das Feld keinen Wert hat und nicht fokusiert ist. Das placeholder-Attribut ist kein Ersatz für ein assoziertes label-Element!</p>
<pre class="brush: xml;">
&lt;label for=&quot;birthday&quot;&gt;Ihr Geburtstag&lt;/label&gt;
&lt;input type=&quot;text&quot; placeholder=&quot;TT.MM.JJJJ&quot; name=&quot;birthday&quot; id=&quot;birthday&quot; /&gt;
</pre>
<p>In HTML4/XHTML 1 ist die Unterscheidung ob das Eingabefeld einen Wert, welcher sich wie ein Placeholder verhalten soll oder nicht, nicht gelöst. Die derzeit eleganteste Javascript-Technik verwendet hierzu einen Vergleich zwischen der value- und der defaultValue-Eigenschaft. Diese Form der Implementierung kommt jedoch an Ihre Grenzen, wenn der User beispielsweise ein Suchformular absendet und der Suchbegriff aus Usability-Gründen wiederholt wird, um es dem User zu gestatten, ohne Neueingabe den Suchbegriff zu erweitern, verkürzen oder sonst wie zu modifizieren. Da in diesem Beispiel ausnahmsweise der defaultValue nicht die Aufgabe eines Placeholders besitzt, fehlt dem Javascript die entscheidende Information sich korrekt zu verhalten. Dieses Problem kann letztlich nur durch Hinzufügen dieser Extrainformation gelöst werden. Und die Standardisierung dieser Extrainformation stellt gerade eben das placeholder-Attribut dar.</p>
<h2>Wie könnte nun eine placeholder-Implementierung aussehen?</h2>
<p>Als erstes erweitern wir unseren oben genannten HTML5-Implementierungstest:</p>
<pre class="brush: jscript;">
var form = $('&lt;form&gt;&lt;fieldset&gt;&lt;input type=“text“ /&gt;&lt;textarea /&gt;&lt;/fieldset&gt;&lt;/form&gt;');

$.extend($.support, {
	checkValidity: !!(form[0].checkValidity),
	textareaMaxlength: !!( $('textarea', form)[0].maxLength !== undefined || $('textarea', form)[0].maxlength !== undefined),
	placeHolder: !!($('input', form)[0].placeholder !== undefined || $('input', form)[0].placeHolder !== undefined)
});
</pre>
<p>Wird das placeholder-Attribut nicht unterstützt, kann mit der Implementierung durch Javascript fortgefahren werden, was wie folgt aussehen könnte.</p>
<pre class="brush: jscript;">
if(!$.support.placeHolder){

	function resetInput(){
		if(this.value == this.getAttribute('placeholder')){
			this.value = '';
		}
	}

	function fillInput(){
		if(!this.value){
			this.value = this.getAttribute('placeholder');
		}
	}
	$(function(){
		$('input[placeholder]')
			.each(function(){
				var placeHolder = this.getAttribute('placeholder').replace(/\n|\r|\f|\t/g, '');
				this.setAttribute('placeholder', placeHolder);
				if(!this.value){
					this.value = placeHolder;
				}

			})
			.bind('blur', fillInput)
			.bind('focus', resetInput)
		;
	});
}
</pre>
<p>Das schöne, das Script kann bereits heute für ein besseres placeholder/input-rest-Script eingesetzt werden. (Ich kenne keines mit einem besseren Verhalten). Bei Browsern (zum Beispiel Safari 4), welche dieses Attribut bereits unterstützen, funktioniert das ganze dann auch ohne Javascript. Die Benutzung ist sehr einfach. Konfiguration und Start des Scripts geschehen komplett automatisch.</p>
<pre class="brush: xml;">
&lt;label for=&quot;birthday&quot;&gt;Ihr Geburtstag&lt;/label&gt;
&lt;input type=&quot;text&quot; id=&quot;birthday&quot; placeholder=&quot;TT.MM.JJJJ&quot; name=&quot;birthday&quot; /&gt;
</pre>
<p>Hier das gesamte Script:</p>
<pre class="brush: jscript;">
(function($){

var form = $('&lt;form&gt;&lt;fieldset&gt;&lt;input type=“text“ /&gt;&lt;textarea /&gt;&lt;/fieldset&gt;&lt;/form&gt;');

$.extend($.support, {
	checkValidity: !!(form[0].checkValidity),
	textareaMaxlength: !!( $('textarea', form)[0].maxLength !== undefined || $('textarea', form)[0].maxlength !== undefined),
	placeHolder: !!($('input', form)[0].placeholder !== undefined || $('input', form)[0].placeHolder !== undefined)
});

if(!$.support.placeHolder){
	$(function(){
		$('input[placeholder]')
			.each(function(){
				var placeHolder = this.getAttribute('placeholder').replace(/\n|\r|\f|\t/g, '');
				this.setAttribute('placeholder', placeHolder);
				if(!this.value){
					this.value = placeHolder;
				}

			})
			.bind('blur', function fillInput(){
				if(!this.value){
					this.value = this.getAttribute('placeholder');
				}
			})
			.bind('focus', function resetInput(){
				if(this.value == this.getAttribute('placeholder')){
					this.value = '';
				}
			})
		;
	});
}
})(jQuery);
</pre>
<h2>Fazit</h2>
<p>HTML 5 hat deutlich mehr zu bieten als nicht funktionierende HTML-Elemente. Diese  sind oftmals nicht mehr als semantischer „Zuckerguß“. HTML 5 kann jetzt schon vielmehr: Es ermöglicht wirklich elegantes und unobtrusives Javascript.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.protofunc.com/2009/08/16/meinung-zu-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
