Cutting Edge

Erforschen Sie reichhaltiges Clientskripting mit jQuery, Teil 1

Dino Esposito

Inhalt

Das jQuery-Objekt
Auswahlen
Filter
Formularfilter
Vorgänge mit umschlossenen Sätzen
Verkettbarkeit von jQuery
Wissenswertes über HTML

Sie wissen ja, wie es ist. Je mehr Funktionalität Sie aus dem Webbrowser herausquetschen wollen, desto mehr Code müssen Sie in JavaScript schreiben. Die JavaScript-Sprache wurde um 1995 eingeführt, um HTML-Seiten aktionsreicher zu gestalten, und war nicht ausdrücklich für Entwickler entworfen worden. Eigentlich war sie entworfen worden, um HTML-Elemente manipulieren, Stile festlegen und auf Benutzereingaben reagieren zu können. Außerdem wurde sie auch häufig für die clientseitige Eingabeüberprüfung und andere einfache Vorgänge verwendet.

Wenn Sie die etwas trivialen Verwendungen sehen, auf die JavaScript angewendet wurde, könnten Sie auf den Gedanken kommen, dass es einfach zu schreiben sei. Aber wie Ray Djajadinata in der Ausgabe des MSDN Magazins vom Mai 2007 in dem Artikel Erstellen fortgeschrittener Webanwendungen mit objektorientierten Verfahren aufgezeigt hat, ist das Schreiben guten JavaScript-Codes keineswegs trivial. Wenn Sie ihn aber gut verstehen, können Sie tatsächlich ziemlich fortgeschrittene Funktionalität aus ihm herauskitzeln.

Einer der Nachteile von JavaScript besteht jedoch darin, dass es eine interpretierte (keine kompilierte) Sprache ist und folglich von der Interpretation des Browsers abhängt. Nicht alle Browser verarbeiten den gleichen JavaScript-Code in der gleichen Art und Weise. Aber mithilfe von Bibliotheken wie jQuery können Sie Ihren JavaScript-Code für mehrere Browser vorhersagbarer gestalten.

Microsoft unterstützt jQuery jetzt vollständig und verteilt es mit dem ASP.NET-MVC-Framework (Model View Controller). Außerdem wurden Erweiterungen entwickelt, um jQuery IntelliSense vollständig in Visual Studio 2008 SP1 zu integrieren.

In der Ausgabe dieses Monats werden die Hauptmerkmale der jQuery-Bibliothek erörtert, mit besonderem Schwerpunkt auf CSS-Auswahlen, Funktionsverkettung und umschlossenen Sätzen. In einer zukünftigen Ausgabe geht es dann um spezifischere Themen wie die Verwendung von jQuery für die Behandlung von Ereignissen und Effekten, browserseitiger Zwischenspeicherung und AJAX-Anforderungen.

jQuery auf einen Blick

Mit jQuery lässt sich JavaScript-Code einfacher und schneller schreiben. Die Bibliothek stellt Hilfsfunktionen bereit, die Ihre Produktivität deutlich erhöhen und Ihre Frustration verringern. Der resultierende Code ist einfacher zu lesen und stabiler, da durch die höhere Abstraktionsebene eine Reihe von Überprüfungen und Fehlerbehandlungsverfahren ausgeblendet werden.

Die von John Resig geschriebene Bibliothek besteht aus einer einzelnen .js-Datei, die Sie unter „docs.jquery.com/Downloading_jQuery“ herunterladen können. Die aktuelle Version ist 1.2.6, die im Frühjahr 2008 veröffentlicht wurde. Auf der Downloadwebsite werden drei Versionen der Bibliothek angeboten: entpackt, gepackt und minimiert.

Die entpackte Version ist nahezu 100 KB groß und vollständig vom Benutzer lesbar und kommentiert. Diese Version ist definitiv für das Durchsehen und Debuggen geeignet.

Die minimierte Version ist etwa 50 KB groß. Alle zusätzlichen Zeichen, die nicht unbedingt für die Implementierung der Funktionalität erforderlich sind, wurden aus dem Quellcode entfernt. Der Code kann nur schwer oder gar nicht von Benutzern gelesen werden, aber für Computer ist er genau richtig.

Die gepackte Version schließlich ist gerade 30 KB groß, benötigt aber mehr Initialisierungszeit auf dem Client. Auf der offiziellen Website von jQuery wird empfohlen, für Produktionsumgebungen die minimierte statt der gepackten Version herunterzuladen. Außerdem sollten Sie beachten, dass GZIP-Komprimierung im Internet üblich ist und von allen modernen Webservern und Browsern verarbeitet werden kann. Durch die GZIP-Komprimierung wird die Größe um ungefähr 20 KB verringert. Wenn Sie GZIP verwenden, ist die gepackte Version ziemlich nutzlos.

In einem ASP.NET-Projekt benötigen Sie außerdem eine jquery-1.2.6-vsdoc.js-Datei, um IntelliSense zu ermöglichen, und ein Visual Studio 2008-Patch (siehe Unterstützung von KB958502-JScript-Editor für „-vsdoc.js“-IntelliSense-Dokumentationsdateien), um jQuery IntelliSense vollständig zu unterstützen.

In ASP.NET können Sie die Bibliothek entweder mit einem einfachen <script>-Tag verknüpfen, oder Sie können sie im Skriptabschnitt des ScriptManager-Steuerelements auflisten, etwa so:

<asp:ScriptManager id="ScriptManager1" runat="server">
    <Scripts>
        <asp:ScriptReference path="Scripts/jquery-1.2.6.min.js" />
    </Scripts>
</asp:ScriptManager>

Dieser Ansatz wird für die aktuelle Version von ASP.NET nicht empfohlen, es sei denn, Sie möchten auch die Microsoft AJAX-Bibliothek in die Seite einbetten. In ASP.NET 4.0 wird es möglich sein, die Einbeziehung von Microsoft AJAX-Clientframeworkdateien zu deaktivieren, sodass dies ein guter Ansatz ist.

Der gesamte Satz an jQuery-Funktionen kann in vier Hauptbereiche eingeteilt werden: DOM-Abfrage und -Bearbeitung, Effekte und Animation, AJAX sowie Kernfunktionen für die Arbeit mit Arrays, die Datenfilterung und das Erkennen von Browserfunktionen.

Das jQuery-Objekt

Das Wort „Query“ (Abfrage) im Namen der Bibliothek sagt alles. Es bezieht sich auf das Ausführen von Abfragen über das DOM der Seite. Von dort erhält jQuery seine Leistungsfähigkeit.

Mit der Bibliothek wird eine leistungsfähige Benutzeroberfläche zum Auswählen von DOM-Elementen bereitgestellt, die weit über die einfache Suche nach Elementen hinausgeht, die mit einer bestimmten ID übereinstimmen. Sie können z. B. problemlos alle Elemente auswählen, die eine bestimmte CSS-Klasse gemeinsam nutzen, bestimmte Attribute haben, an einer bestimmten Position in der Struktur auftreten oder eine Beziehung zu anderen Elementen haben. Noch wichtiger ist, dass Sie Filterbedingungen hinzufügen und alle diese Abfragefeatures verketten können, ähnlich wie beim Abfragen von Daten in SQL.

Der Stamm der jQuery-Bibliothek ist die jQuery-Funktion, die folgendermaßen definiert ist:

var jQuery = window.jQuery = window.$ = function( selector, context ) 
{
   return new jQuery.fn.init( selector, context );
};

Die $-Funktion ist ein Alias für die jQuery-Funktion. Wenn Sie ein jQuery-Objekt erstellen, übergeben Sie eine Auswahl und einen Kontext. Mit der Auswahl wird der Abfrageausdruck angezeigt. Mithilfe des Kontexts wird der Anteil des DOM angegeben, für den die Abfrage ausgeführt werden soll. Wenn kein Kontext angegeben ist, wird mit der jQuery-Funktion im gesamten Seiten-DOM nach DOM-Elementen gesucht.

Die jQuery-Funktion (sowie ihr $-Alias) führt einige Arbeiten an den bereitgestellten Argumenten durch, führt die Abfrage aus und gibt dann ein neues jQuery-Objekt zurück, das die Ergebnisse enthält. Das neu erstellte jQuery-Objekt wiederum kann in einer neuen Anweisung sowie in einer Kette von Anweisungen weiter abgefragt oder gefiltert werden.

Das Stammobjekt von jQuery unterstützt folgende Signaturen:

jQuery( expression, [context] )
jQuery( html, [ownerDocument] )
jQuery( elements )
jQuery( callback )

Die erste übernimmt eine CSS-Auswahl und gibt ein gewrapptes Array von HTML-Elementen zurück, den so genannten umschlossenen Satz. Die zweite akzeptiert eine HTML-Zeichenfolge, erstellt die verwandte Unterstruktur und fügt diese gegebenenfalls an die angegebenen Besitzerdokumente an. Die dritte Überladung holt die angegebenen DOM-Elemente ab. Abschließend nimmt die vierte einfach eine Rückruffunktion und führt diese für das gesamte Dokument aus, sobald das Dokument der Seite vollständig geladen ist.

Außerdem verfügt das Stammobjekt von jQuery auch über einige Hilfsmethoden, die in Abbildung 1 aufgelistet sind. Von besonderem Interesse für Entwickler ist die each-Methode. Diese können Sie als Kurzform für eine manuelle Iteration über den Inhalt eines jQuery-Objekts verwenden – in der Regel die über eine CSS-Auswahl ausgewählten DOM-Elemente. Es folgt ein Codeausschnitt, der die each-Methode in Aktion zeigt. Die Schleife verarbeitet alle <input>-Tags in einem Formular:

$("form input").each(
    function(i) {
            this.title = "Input #" + i;    
}
);
Abbildung 1 Edgeserverrollen und Reverseproxy für OCS 2007
Methoden Beschreibung
each( Rückruf ) Durchläuft in einer Schleife den Inhalt des umschlossenen Satzes und führt die angegebene Rückruffunktion aus.
length Eigenschaft, mit der die Anzahl der Elemente im umschlossenen Satz zurückgegeben wird.
eq( Position ) Reduziert den umschlossenen Satz auf das einzelne Element an der angegebenen Position.
get() Gibt der Inhalt des umschlossenen Satzes als Array von DOM-Elementen zurück.
get( Index ) Gibt die DOM-Elemente an der angegebenen Position des umschlossenen Satzes zurück.
index( Element ) Gibt den 0-basierten Index im umschlossenen Satz des angegebenen DOM-Elements zurück, falls vorhanden.

Der Unterschied zwischen each() und einer manuellen JavaScript-Schleife besteht darin, dass each() das „this“-Objekt automatisch dem Element in der Auflistung zuordnet, das verarbeitet wird. Die Rückruffunktion erhält jedoch einen optionalen Ganzzahlparameter, der der (0-basierte) Index der Iteration ist. Sehen wir uns jQuery-Auswahlen und deren CSS-basierte Syntax genauer an.

Es folgt die einfachste Verwendung der $-Funktion:

var elem = $("#grid");

Mit der $-Funktion im Codeausschnitt werden alle DOM-Elemente abgerufen, deren ID-Eigenschaft mit dem angegebenen Ausdruck übereinstimmt. Das #-Symbol gehört nicht in die ID-Zeichenfolge. Es ist lediglich ein Präfix für die $-Funktion, um ID-Zeichenfolgen, CSS-Klassen und Namen von HTML-Tags eindeutig zu machen. (Das #-Symbol ist Bestandteil der standardmäßigen CSS-Syntax für die ID-Auswahl.) Der vorhergehende Codeausschnitt ist funktional gleichwertig mit der folgenden DOM-Anweisung:

var elem = document.getElementById("grid");

Beachten Sie, dass im HTML-DOM im Unterschied zu ASP.NET mehrere Elemente die gleiche ID nutzen können. Wenn ein Array von Elementen mit der ID übereinstimmt, würde die Methode „getElementById“ nur das erste übereinstimmende Element zurückgeben. Die Methode „getElementsByName“ andererseits würde die ganze Auflistung zurückgeben.

An dieser Stelle endet die Ähnlichkeit zwischen den klassischen DOM-Methoden und der $-Funktion. Die Leistungsfähigkeit von $ geht weit darüber hinaus. Mittels $ wählen Sie DOM-Elemente aus und wenden dann eine Funktion auf jedes Element an.

Der Auswahlausdruck wird von der CSS 3.0-Syntax gesteuert und kann ein nicht triviales Maß an Komplexität erreichen. In Abbildung 2 werden die unterstützten Auswahlen angezeigt. Die Liste enthält keine Filter. Darauf wird sogleich eingegangen. In einer Hierarchie von Auswahlen muss unbedingt beachtet werden, dass es sich bei dem Vorgängerelement, dem übergeordneten Element oder dem früheren Element um eine beliebige Auswahl handeln kann, nicht bloß um ein HTML-Element. In Abbildung 3 sind einige Beispielabfragen dargestellt.

Abbildung 2 Unterstützte jQuery-Auswahlen
Auswahl Beschreibung
#id Gibt gegebenenfalls das erste Element im DOM mit einem entsprechenden ID-Attribut zurück.
element Gibt alle Elemente mit einem übereinstimmenden Tagnamen zurück.
.class Gibt alle Elemente mit einer übereinstimmenden CSS-Klasse zurück.
* Gibt alle Elemente auf der Seite zurück.
selector1, ..., selectorN Wendet alle gegebenen grundlegenden Auswahlen an und gibt die kombinierten Ergebnisse zurück.
ancestor descendant Wenn eine Auswahl für ein Vorgängerelement vorhanden ist, wird damit die Auflistung aller Nachfolgerelemente zurückgegeben, die mit der Auswahl des Nachfolgerelements übereinstimmen. Mit „div p“ werden z. B. alle <p>-Elemente innerhalb eines <div> zurückgegeben.
parent > child Wenn eine Auswahl vorhanden ist, wird damit die Auflistung aller untergeordneten Elemente zurückgegeben, die mit der untergeordneten Auswahl übereinstimmen.
prev + next Wenn eine Auswahl vorhanden ist, wird damit die Auflistung aller gleichgeordneten Elemente zurückgegeben, die mit der nächsten Auswahl übereinstimmen und sich neben der prev-Auswahl befinden.
prev ~ sibling Wenn eine Auswahl vorhanden ist, wird damit die Auflistung aller gleichgeordneten Elemente zurückgegeben, die mit der nächsten Auswahl übereinstimmen und der prev-Auswahl folgen.
Abbildung 3 Beispiele für jQuery-Auswahlen in Aktion
Beispielauswahl Auswirkungen
form input Gibt alle Eingabefelder innerhalb aller <form>-Tags auf der Seite zurück.
#Form1 input Gibt alle Eingabefelder im Formular mit der Beschriftung „Form1“ zurück.
h2 + p Gibt alle <p>-Tags zurück, die neben einem <h2> stehen und ein untergeordnetes Element des gleichen übergeordneten Elements sind.
input.textBox Gibt alle <input>-Tags zurück, deren CSS-Klasse „textBox“ ist.
div span.myClass Gibt alle <span>-Tags zurück, deren CSS-Klasse „myClass“ ist und die sich in einem <div> befinden.

Auswahlen können weiter verfeinert werden, indem Filter auf Attribute, Inhalt, Position und Sichtbarkeit angewendet werden. In Abbildung 4 sind einige der beliebtesten Filter in jQuery aufgelistet. Die vollständigen Referenzinformationen finden Sie unter „doc.jquery.com/Selectors“.

Mit Filtern wie „first“ und „last“ wird an einer bestimmten Position in der zurückgegebenen Auflistung nach DOM-Elementen gesucht. Sie können auch eine indexbasierte Syntax verwenden, um Elemente mithilfe der Filter „eq“, „gt“ und „lt“ zu filtern. Mit dem Filter „eq“ wird das Element aufgenommen, dessen Index mit dem gegebenen Index übereinstimmt, während mit „gt“ und „lt“ Elemente aufgenommen werden, die größer oder kleiner als ein bestimmter Index sind.

Attributfilter sind leistungsfähige Tools, mit denen HTML-Elemente ausgewählt werden, bei denen sich ein bestimmtes Attribut in einer bestimmten Beziehung zu einem Wert befindet. In Abbildung 4 sind nur die gebräuchlichsten Attributfilter aufgelistet. Es gibt weitere Filter, um Elemente auszuwählen, bei denen ein bestimmtes Attribut mit einem bestimmten Wert beginnt oder endet oder diesen enthält. Dies ist die erforderliche Syntax:

[attribute^=value]  // begins with value
[attribute$=value]  // ends with value
[attribute*=value]  // contains value
Abbildung 4 jQuery-Filter
Positionsfilter Beschreibung
:first Gibt das erste Element der ausgewählten Auflistung von Elementen zurück.
:last Gibt das letzte Element der ausgewählten Auflistung von Elementen zurück.
:not(selector) Filtert alle Elemente heraus, die mit der angegebenen Auswahl übereinstimmen.
:even Gibt alle geraden Elemente in der ausgewählten Auflistung zurück.
:odd Gibt alle ungeraden Elemente in der ausgewählten Auflistung zurück.
Untergeordnete Filter Beschreibung
:nth-child(expr) Gibt alle untergeordneten Elemente eines beliebigen übergeordneten Elements zurück, die mit dem gegebenen Ausdruck übereinstimmen. Bei dem Ausdruck kann es sich um einen Index oder eine mathematische Folge handeln (z. B. 3n+1), einschließlich Standardsequenzen wie „odd“ und „even“.
:first:child Gibt alle Elemente zurück, die das erste untergeordnete Element ihres übergeordneten Elements sind.
:last-child Gibt alle Elemente zurück, die das letzte untergeordnete Element ihres übergeordneten Elements sind.
:only-child Gibt alle Elemente zurück, die das einzige untergeordnete Element ihres übergeordneten Elements sind.
Inhaltsfilter Beschreibung
:contains(text) Gibt alle Elemente zurück, die den angegebenen Text enthalten.
:empty Gibt alle Elemente ohne untergeordnete Elemente zurück. (Text wird als untergeordneter Knoten betrachtet.)
:has(selector) Gibt alle Elemente zurück, die mindestens ein Element enthalten, das mit der gegebenen Auswahl übereinstimmt.
:parent Gibt alle Elemente zurück, die mindestens ein untergeordnetes Element besitzen. (Text wird als untergeordneter Knoten betrachtet.)
Sichtbarkeitsfilter Beschreibung
:hidden Gibt alle Elemente zurück, die derzeit ausgeblendet sind. Ausgeblendete Eingabeelemente werden der Liste hinzugefügt.
:visible Gibt alle Elemente zurück, die derzeit sichtbar sind.
Attributfilter Beschreibung
[attribute] Gibt alle Elemente zurück, die das angegebene Attribut besitzen.
[attribute = value] Gibt alle Elemente zurück, deren angegebener Attributsatz auf den angegebenen Wert gesetzt ist.
[attribute != value] Gibt alle Elemente zurück, deren angegebenes Attribut (falls vorhanden) einen Wert hat, der sich vom angegebenen unterscheidet.

Attributfilter können auch verkettet werden, indem einfach zwei oder mehr von ihnen nebeneinander platziert werden, etwa so:

[align=right][valign=top]

Ein besonders leistungsfähiger Filter ist „nth-child“ Dieser unterstützt, wie hier zu sehen, eine Reihe unterschiedlicher Eingabeausdrücke:

:nth-child(index)
:nth-child(even)
:nth-child(odd)
:nth-child(sequence) 

Mit dem ersten Format wird das n-te untergeordnete Element aus den HTML-Elementen in der Quellauswahl ausgewählt, wobei sich „n“ auf den bereitgestellten Index bezieht. Alle Elemente, die an einer beliebigen geraden oder ungeraden Position (0-basiert) platziert werden, werden zurückgegeben, wenn Sie den Filter „even“ oder „odd“ angeben. Abschließend können Sie das n-te untergeordnete Element als Stammausdruck einer mathematischen Folge wie 3n übergeben, um Vielfache von 3 anzuzeigen.

Beispiel: Mit der folgenden Auswahl werden alle Zeilen in einer Tabelle (mit der Beschriftung „DataGrid1“) abgerufen, die sich an den Positionen befinden, die der Folge 3n+1 entsprechen (1, 4, 7 usw., wobei es sich um einen nullbasierten Index handelt):

#DataGrid1 tr:nth-child(3n+1)

Der nächste Ausdruck ist viel komplexer und demonstriert die unglaubliche Leistungsfähigkeit und Flexibilität von jQuery-Auswahlen:

#DataGrid1 tr:nth-child(3n+1):has(td[align=right]) td:odd

Er liest sich folgendermaßen: von allen im vorherigen Schritt ausgewählten Tabellenzeilen (1, 4, 7 usw.) übernehmen Sie jetzt nur jene, die eine Zelle haben (ein <td>-Tag), in der das Attribut „align“ den Wert „right“ hat. Außerdem übernehmen Sie aus den übrigen Zeilen nur die Zellen in Spalten mit einem ungeraden Index. Betrachten Sie die HTML-Tabelle in Abbildung 5. In Abbildung 6 ist die Zelle mit dem gelben Hintergrund das Ergebnis der Abfrage.

Abbildung 5 Eine HTML-Tabelle

<table id="DataGrid1" border="1">
    <tr>
       <td>Column1</td>
       <td>Column2</td></tr>
    <tr>
       <td>Val1</td>
       <td align="right">Num1</td></tr>
    <tr>
       <td>Val2</td>
       <td align="right">Num2</td></tr>
    <tr>
       <td>Val3</td>
       <td align="right">Num3</td></tr>
    <tr>
       <td>Val4</td>
       <td>Num4</td></tr>
    <tr>
       <td>Val5</td>
       <td>Num5</td></tr>
    <tr>
       <td>Val6</td>
       <td>Num6</td></tr>
    <tr>
       <td>Val7</td>
       <td>Num7</td></tr>
</table>

fig06.gif

Abbildung 6 Auswählen einer bestimmten Zelle in einer Tabelle

Formularfilter

Wie bereits erwähnt, ähnelt die Gesamtsyntax von jQuery-Auswahlen sehr der Syntax von CSS 3.0-Auswahlen. Sie wurde lediglich durch einige zusätzliche Pseudoelemente wie jenen erweitert, die in Abbildung 7 aufgelistet sind.

Insbesondere der Filter „:input“ bezieht sich auf alle logischen Eingabeelemente, die Sie u. U. auf einer Seite finden, und ist nicht auf die <input>-Tags begrenzt. Tatsächlich enthält er <textarea>- und <select>-Elemente, mit denen Listenfelder und Dropdownlisten angezeigt werden. Die Auswahlen in Abbildung 7 stimmen nicht mit CSS-Auswahlen überein, stellen aber nützliche Verknüpfungen bereit, um homogene Elemente wie z. B. alle Eingabetags eines bestimmten Typs abzurufen. Die Auswahl „:text“ ist z. B. funktional gleichwertig mit Folgendem:

form input[type=text]
Abbildung 7 Formularfilter
Auswahl Beschreibung
:input Gibt alle Elemente zurück, die eine Rolle beim Sammeln von Eingabedaten spielen, einschließlich Textbereichen und Dropdownlisten.
:text Gibt alle Eingabeelemente zurück, deren Typattribut „text“ ist.
:password Gibt alle Eingabeelemente zurück, deren Typattribut „password“ ist.
:checkbox Gibt alle Eingabeelemente zurück, deren Typattribut „checkbox“ ist.
:radio Gibt alle Eingabeelemente zurück, deren Typattribut „radio“ ist.
:submit Gibt alle Eingabeelemente zurück, deren Typattribut „submit“ ist.
:reset Gibt alle Eingabeelemente zurück, deren Typattribut „reset“ ist.
:image Gibt alle Eingabeelemente zurück, deren Typattribut „image“ ist.
:button Gibt alle Eingabeelemente zurück, deren Typattribut „button“ ist.
:file Gibt alle Eingabeelemente zurück, deren Typattribut „file“ ist.
:hidden Gibt alle Eingabeelemente zurück, deren Typattribut „hidden“ ist.
:enabled Gibt alle Eingabeelemente zurück, die derzeit aktiviert sind.
:disabled Gibt alle Eingabeelemente zurück, die derzeit deaktiviert sind.
:checked Gibt alle Kontrollkästchen- oder Optionsfeldelemente zurück, die derzeit aktiviert sind.
:selected Gibt alle Listenelemente zurück, die derzeit ausgewählt sind.

Es gibt weitere nützliche Hilfsprogramme, um alle Eingabeelemente auf einer Seite, die aktiviert oder deaktiviert sind, sowie derzeit ausgewählte Listenelemente abzurufen.

Vorgänge mit umschlossenen Sätzen

HTML-Elemente, die mit einer Auswahl übereinstimmen, werden in eine neue Instanz des jQuery-Objekts gepackt zurückgegeben. Dieses Objekt beinhaltet ein JavaScript-Array mit allen DOM-Verweisen. Die Ergebnisse werden oft als umschlossener Satz bezeichnet. Ein umschlossener Satz ist nie null, selbst wenn keine übereinstimmenden Elemente gefunden wurden. Prüfen Sie diese Situation, indem Sie sich, wie hier gezeigt, die length-Eigenschaft des jQuery-Objekts ansehen:

// All TDs with a child IMG
var w_set = new jQuery("#DataGrid1 td:has(img))");
if (w_set.length == 0)
    alert("No match found.");
else
    alert(w_set.length)

Das hohe Maß an Flexibilität, das von jQuery geboten wird, ist äußerst nützlich. Aber sobald Sie alle Elemente haben, nach denen Sie gesucht haben, müssen Sie sie verarbeiten. Der einfachste mögliche Ansatz erfordert das Einrichten einer Schleife und das Ausführen einer Funktion für jedes Element in der Auflistung, etwa so:

var ws = $("#DataGrid1 tr:nth-child(3n+1)");
for(i = 0; i<ws.length; i++)
{
   processElement(ws[i]);
}
function processElement(elem)
{
   ...
}

In einer solchen manuellen Iteration greifen Sie direkt auf DOM-Elemente zu, genauso wie bei der klassischen JavaScript-Programmierung.

Mit der jQuery-Bibliothek werden einige alternative Routen angeboten, die funktional gleichwertig zu manueller Iteration sind. Erfreulicherweise führen jQuery-Iterationen zu Code, kompakter und sogar lesbarer ist. Der erste Ansatz basiert auf der each-Funktion.

Wie bereits erwähnt, wird in jQuery mit der each-Funktion ein benutzerdefinierter Rückruf an ein beliebiges Element ausgeführt, das dem umschlossenen Satz zugeordnet ist. Es gibt jedoch eine ziemlich große Anzahl an Betriebsmethoden, mit denen Sie gängige Vorgänge am umschlossenen Satz noch schneller und einfacher ausführen können. Mit der css-Funktion können Sie z. B CSS-Stile auf den umschlossenen Satz anwenden. Es folgt ein Beispiel, in dem Hintergrundfarbe und Rahmenstil für alle Eingabeelemente in einem Formular festgelegt werden:

$("form input").css(
   {'background-color' : 'yellow', 
    'border-style' : 'dashed'}
); 

Zugegeben, dieses kurze Beispiel ist ein wenig irreführend, da es suggerieren kann, dass jQuery für Aufgaben verwendet werden sollte, die CSS selbst gut erledigen kann. Die css-Funktion ist großartig, wenn damit an dynamisch angewendeten Stilen gearbeitet wird, die von Benutzereingriffen oder anderen Laufzeitbedingungen abhängen.

Ebenso können Sie für die Elemente in dem umschlossenen Satz eine CSS-Klasse hinzufügen, entfernen und sogar wechseln. Dies erledigen Sie über die addClass-, removeClass- und toggleClass-Funktionen. Mit der attr-Funktion können Sie eines oder mehrere Attribute für alle Elemente festlegen. Hier wird z. B. gezeigt, wie alle Eingabeelemente deaktiviert werden:

$("form input").attr(
   {'disabled' : 'disabled'}
); 

Mit der html-Funktion wird der HTML-Inhalt eines Tags festgelegt. Die innerHTML-Eigenschaft wird intern verwendet. Um den inneren Text eines Tags festzulegen, verwenden Sie stattdessen die Textfunktion, mit der der Text übergegeben wird, der als Argument festgelegt werden soll. Dies ist eine gute Möglichkeit, die Vorteile einer browserübergreifenden Bibliothek wie jQuery zu verstehen. Die innerHTML-Eigenschaft kann de facto als Standardeigenschaft betrachtet werden, die von allen Browsern auf gleiche Weise unterstützt wird.

Das Gleiche kann nicht für die analoge Eigenschaft gesagt werden, mit der der Text lediglich festgelegt wird. Diese Eigenschaft heißt in Internet Explorer „innerText“ und in Firefox „text­Element“. Die jQuery-Textfunktion blendet Unterschiede aus und stellt die gleiche Funktionalität für alle Browser bereit.

Verkettbarkeit von jQuery

Eine der besten Eigenschaften von jQuery ist seine Verkettbarkeit, die möglich ist, weil das jQuery-Objekt selbst sowie die meisten Funktionen und Filter ein jQuery-Objekt zurückgeben. Das zurückgegebene Objekt enthält den ursprünglichen umschlossenen Satz, so wie er von der Funktion selbst geändert wurde. Wenn Sie z. B. die css-Funktion auf einen umschlossenen Satz anwenden, enthält das zurückgegebene jQuery-Objekt den gleichen Satz an Elementen zusammen mit einem geänderten Satz von CSS-Stilen. Wenn Sie einen Filter anwenden, erhalten Sie einen kleineren Satz zurück, wie von der Funktion gefiltert. Es ist zu beachten, dass auch eine not-Funktion verfügbar ist, um alle Elemente auszuschließen, die mit der angegebenen Abfrage übereinstimmen.

Das Verketten von jQuery-Funktionen könnte einfacher nicht sein. Sie müssen an das vom früheren Aufruf zurückgegebene jQuery-Objekt lediglich einen neuen Funktionsaufruf anfügen. Hier ist ein Beispiel:

$("form input")
.not("[type!=text]")
.css(
   {'background-color' : 'yellow', 
    'border-style' : 'dashed'})
.attr("value", "test"); 

Mit dem Beispielausdruck werden alle Eingabefelder ausgewählt, in denen das type-Attribut gleich „text“ ist, und einige CSS-Stile festgelegt. Das value-Attribut wird auf feste Werte gesetzt. (Im Beispiel wurde der Kette mithilfe der not-Funktion lediglich ein dritter Link hinzugefügt. Das Ergebnis der not-Bedingung könnte in die $-Abfrage integriert werden, was zu noch klarerem Code führt.)

Es versteht sich von selbst, dass durch die Methode des Verkettens kompakterer Code entsteht. Dies führt aber nicht unbedingt zu schnellerem Code. Verkettung ist ein Verfahren, mit dem Sie als Entwickler sich wohl fühlen oder auch nicht. Wenn Sie mit einem dieser kompakten Ausdrücke Schwierigkeiten haben, möchten Sie diesen u. U. in kleine Stücke unterteilen, um das Debuggen zu vereinfachen.

Beachten Sie abschließend, dass nicht von allen jQuery-Methoden ein geändertes jQuery-Objekt zurückgegeben wird. Mit Methoden wie „html“ oder „text“ z. B. wird lediglich eine Zeichenfolge zurückgegeben, die jeweils auf den HTML- oder Textinhalt des ersten Elements des umschlossenen Quellsatzes zeigt. Die genaue Syntax von jQuery-Methoden finden Sie unter „docs.jquery.com/Main_Page“.

Wissenswertes über HTML

Je mehr Sie in die Tiefen von jQuery eindringen, desto besser verstehen Sie, wie wichtig es ist, das HTML, mit dem Sie arbeiten, genau zu kennen. ASP.NET-Serversteuerelemente neigen dazu, die Struktur des HTML auszublenden, das sie ausgeben. Andererseits wurden Serversteuerelemente nur eingeführt, damit Entwickler sich auf deklarative Attribute statt auf HTML-Details konzentrieren können. Jahrelange Erfahrung hat gezeigt, dass dies nicht immer der richtige Ansatz war.

Heutzutage müssen Sie Ihr HTML zwecks Zugänglichkeit, Gestaltung und Übereinstimmung mit XHTML vollständig unter Kontrolle behalten. Übrigens wird durch diese Tatsache eine subtile Verknüpfung zwischen jQuery und dem ASP.NET MVC Framework hergestellt. Außerdem ist es kein Zufall, dass das ASP.NET MVC Framework die aktuelle Version von jQuery im Paket enthält.

Andererseits ist auch zu beachten, dass das Binden von Logik an Markup mithilfe von jQuery-Auswahlen zu einer unerwünschten Kopplung zwischen Logik und der Form des DOM führen kann, was u. U. schwierig zu verwaltende Anwendungen zur Folge hat.

Wenn Sie auf der Suche nach weiteren Ideen für interessante Verwendungsmöglichkeiten von JavaScript sind, sehen Sie sich die Liste der JavaScript-Artikel auf MSDN an.

Senden Sie Fragen und Kommentare für Dino Esposito in englischer Sprache an cutting@microsoft.com.

Dino Esposito ist Architekt bei IDesign und Mitautor von Microsoft. NET: Architecting Applications for the Enterprise (Microsoft Press, 2008). Er lebt in Italien und ist ein weltweit gefragter Referent bei Branchenveranstaltungen. Sie finden seinen Blog unter weblogs.asp.net/despos.