Javascript-Knigge

Mit Behaviour liegt eine Bibliothek vor, die es erlaubt, Javascript-Code vollständig aus HTML auszulagern - durch Zuordnung von Event-Handlern mit CSS-Selektoren.

In Pocket speichern vorlesen Druckansicht 42 Kommentare lesen
Lesezeit: 7 Min.
Von
  • Stefan Mintert
Inhaltsverzeichnis

Formatierungsanweisungen lassen sich mittlerweile gut aus HTML-Seiten heraushalten. Zu verdanken ist dies den Cascading Stylesheets (CSS). Zwar gibt es unter den meistverbreiteten Browsern noch viele Unterschiede - gerade die jüngeren CSS-Funktionen haben noch keine flächendeckende Unterstützung erfahren -, aber es gibt einen CSS-Kern, den alle beherrschen.

Mit einem Working Draft hat das World Wide Web Consortium (W3C) 1999 einen Entwurf vorgelegt, außer der Formatierung von Elementen ihr Verhalten (engl.: behaviour) ebenfalls außerhalb von HTML zu definieren (siehe „Online-Ressourcen“, Zeile 3). Das Verhalten eines HTML-Elements lässt sich am besten mit einem Script beschreiben (beispielsweise in Java-script programmiert), das einen Event-Handler an ein Element bindet. Wie diesen ein Verhalten zugewiesen wird, ist CSS entlehnt.

Mehr Infos

Ziel der CSS war es unter anderem, das Webseiten-Layout von deren Struktur zu trennen (wenn man die Stilanweisungen nicht in die einzelnen Elemente packt). Kurz gesagt besteht der Aufbau einer CSS-Anweisung aus einer Zuordnung. Auf deren linker Seite steht der Selektor, der angibt, für welches/welche Elemente eine Formatierungsanweisung gültig ist. Auf der rechten Seite steht die Formatierungsanweisung: h1 { color: red; }

Nun ist es naheliegend, die rechte Seite um Script-Code zu erweitern, der das Verhalten im Falle eines bestimmten Ereignisses festlegt. Daher überrascht es nicht, dass das erste Codebeispiel im genannten W3C-Working-Draft etwa wie folgt aussieht:

div.header > h1.TOCtitle {
color : red ;
onclick : “fold_or_unfoldTOC(event)”
}

Für bestimmte h1-Elemente definieren obige Zeilen den Event-Handler onclick. Das fast sieben Jahre alte W3C-Papier ist über den Status „Arbeitsentwurf“ allerdings nicht hinausgekommen, was damit zu tun haben dürfte, dass das Konsortium Ereignisbehandlung an mehreren anderen Stellen bearbeitet: eine Empfehlung (Recommendation) für XML Events und für DOM Events.

Eine Notation wie oben hätte den Vorteil, dass die gelegentlich massenhaft in HTML-Dokumenten vorkommenden

<span class=”wichtig”
onmouseover=”...”
onmouseout=”...” onclick=”...”>...</span>

der Vergangenheit angehören und in HTML tatsächlich nur noch HTML steht.

Event-Verarbeitung auf allgemeinerer Ebene zu bearbeiten, ist durchaus sinnvoll. Schließlich gilt alles, was für XML „erfunden“ wird, automatisch für HTML - zumindest in der Geschmacksrichtung XHTML. Auf der anderen Seite kann für HTML nur interessieren, was Browserhersteller wirklich implementiert haben. Nicht alles, was das W3C verabschiedet, gehört dazu. Die Recommendation für XML Events stammt aus dem Oktober 2003, aber dazu fähige HTML-Browser sind nicht bekannt.

Der Entwickler Ben Nolan hat sich des Dilemmas angenommen und eine Javascript-Bibliothek entwickelt, die sich weitgehend an die oben genannte, ursprüngliche Idee anlehnt. Nolan schreibt auf seiner Webseite (siehe „Online-Ressourcen“): „Behaviour is the missing link for your ajax apps.“ Es gibt keinen unmittelbaren technischen Bezug zwischen Behaviour und Ajax, allerdings ist Nolans Argumentation nachvollziehbar: Ajax-Anwendungen erfordern ein gewisses Maß an Javascript und Event-Handlern. Aus diesem Grund liegt es nahe, die Funktionsweise seiner Bibliothek anhand des Ajax-Artikels aus der November-iX (siehe [1]) zu erklären.

Dort beschrieb das Codebeispiel die Anfrage an ein XML-Wörterbuch - die URL ist in Zeile 5 der „Online-Ressourcen“ zu finden. Der Code besteht aus einer HTML-Seite mit einem umfangreichen Script-Element und einer Reihe von Event-Handlern. Bekanntlich lässt sich der Inhalt des Script-Elements leicht auslagern. An seine Stelle tritt eine externe Javascript-Datei, die das Webdokument per

<script type=”text/javascript” src=”xmlad.js” /> 

einbindet (hier in XHTML-Syntax). Nun kommt die spannende Stelle, an der die Event-Handler aus dem Code entfernt werden sollen. Bisher steht in HTML ein input-Element mit onkeyup (siehe Listing 1) und insgesamt achtmal

<input type=”radio” name=”typ”
onclick=”showAcroList()” value=”...” />
Mehr Infos

Listing 1: input mit onkeyup

<input id="input" 
onkeyup="if (this.value.length &gt; 1)
{loadAcroList(this.value);}"
onblur="if (this.value.length &lt; 2)
{loadAcroList(this.value);}"
type="text" name="input" />

In der neuen Fassung soll es in HTML so aussehen:

<input id=”input” type=”text” name=”input”/>
... <input type=”radio” name=”typ” value=”...”/>

Eine CSS-Lösung im Sinne des W3C-Working-Draft nähme die Form von Listing 2 an.

Mehr Infos

Listing 2: CSS mit Verhaltenscode

#input { 
onkeyup: "if (this.value.length > 1)
{loadAcroList(this.value);}";
onblur: "if (this.value.length < 2)
{loadAcroList(this.value);}";
}
input[type=radio][name=typ] {
onclick: "showAcroList()";
}

Nolan ist mit seinem Ansatz nah daran, wenngleich die Javascript-Lösung naturgemäß eine andere Gestalt annimmt. Mit Behaviour sieht es aus wie Listing 3.

Mehr Infos

Listing 3: Lösung mit Nolans Behaviourvar

 xmladRules = {
'#input' : function(element){
element.onkeyup = function(){
if (this.value.length > 1)
{loadAcroList(this.value);}
}
element.onblur = function(){
if (this.value.length < 2)
{loadAcroList(this.value);}
}
},
'input[type=radio][name=typ]' : function(element){
element.onclick = function(){
showAcroList()
}
}
};
Behaviour.register(xmladRules);

Was Ben Nolan hier als Notation verlangt, verrät schon, wie seine Bibliothek funktioniert. Behaviour verwendet ein assoziatives Array, dessen Indexwerte die CSS-Regeln bilden (beispielsweise #input). Beim zugeordneten Wert handelt es sich jeweils um eine (namenlose) Funktion mit genau einem formalen Parameter, der hier den Namen element trägt. Es handelt sich dabei um ein DOM-Objekt vom Typ Element. Die Funktion fügt dem Objekt den gewünschten Event-Handler-Code durch Definieren der entsprechenden Objekt-Eigenschaft (wie element.onkeyup) hinzu.

Die Methode Behaviour. register() legt die soeben definierten Regeln auf einem Stack ab, der nach dem Laden der Seite abgearbeitet wird. Dazu verwendet Behaviour den onload-Event des document-Objekts. Sobald die Seite geladen ist, werden die Event-Handler aktiviert. Sollte ein Javascript die Webseite per DOM-Programmierung verändern, etwa Elemente hinzufügen, so steht mit Behaviour.apply() eine Methode zur Verfügung, die Regeln zu einem beliebigen Zeitpunkt auf neue Elemente anzuwenden.

Was jetzt noch fehlt, ist sowohl Behaviour als auch die in einer externen Javascript-Datei gehaltenen Regeln in die HTML-Seite zu laden. Listing 4 zeigt das.

Mehr Infos

Listing 4: Behaviour-Einbindung in HTML

<script type="text/javascript" src="behaviour.js" />
<script type="text/javascript" src="xmladBehaviourRules.js" />

Hinsichtlich der internen Programmierung bleibt nur eine Frage offen: Wie schafft Nolan es, zu einem gegebenen CSS-Selektor das passende Element im DOM-Baum zu finden? Die Antwort lautet: Nicht er schafft es, sondern Simon Willison. Von ihm stammt die Methode document.getElementsBySelector, auf der Behaviour basiert (siehe den vorletzten Eintrag in den „Online-Ressourcen“).

Behaviour ist eine elegante Option, den eigenen HTML-Code scriptfrei zu halten. Auf den ersten Blick wäre eine „native“ CSS-Implementierung in den Browsern besser als eine mit Javascript. Auf der anderen Seite geht es hier um Fälle, in denen sowieso Scripting zum Einsatz kommt. Die Verwendung einer weiteren Bibliothek ändert daran nichts. Nolans Javascript-Bibliothek ist außerdem ein eleganter, sauberer Stil zu bescheinigen. Die einfache Verwendbarkeit macht den positiven Eindruck perfekt.

Stefan Mintert
ist Berater und Geschäftsführer von Linkwerk.com.

[1] Stefan Mintert; Webentwicklung; Zwei Helden; Ajax: die nächste Generation der Web-Anwendungen; iX 11/2005, S. 56 (hb)