Plug-in-Enwticklung mit jQuery

Grundregeln der Plug-in-Entwicklung
Kommentare

Zur Entwicklung jeglicher Art von jQuery-Plug-ins ist das Befolgen der in diesem Abschnitt vorgestellten Grundregeln ein guter Ausgangspunkt, um schnell und erfolgreich das gewünschte Ziel zu erreichen. Einige der Regeln sind zwingend erforderlich, um ein lauffähiges Plug-in zu produzieren, andere sind lediglich guter Stil. Trotzdem wird ausdrücklich empfohlen, alle diese Regeln zu befolgen, um eine möglichst unkomplizierte Entwicklungsphase zu gewährleisten.

Konventionen zur Namensgebung

Bevor mit der Entwicklung begonnen werden kann, muss zunächst ein Dateiname für den späteren Plug-in-Quelltext ausgewählt werden. Bevor das geschehen kann, muss das Plug-in selbst zunächst einen Namen erhalten. Ein Name, der dessen Aufgabe möglichst präzise beschreibt, ist wünschenswert. Im Folgenden wird angenommen, das neue Plug-in trägt den äußerst kreativen Namen MyPlug-in. Ist diese Entscheidung gefallen, kann ein Dateiname gebildet werden. jQuerys Regeln diesbezüglich sind relativ strikt. Nicht nur, wenn eine spätere Aufnahme in das jQuery-Plug-in-Verzeichnis angestrebt wird, bietet es sich an, die folgende Konvention zu befolgen:

Der JavaScript-Quelltext jedes Plug-ins sollte sich in einer Datei mit dem Namen jquery.[Plug-inname].js befinden

In dem hier skizzierten Szenario wäre das also jquery.myPlug-in.js. Grundsätzlich sind alle Buchstaben im Dateinamen klein zu schreiben, um Probleme auf Systemen zu vermeiden, die zwischen Groß- und Kleinbuchstaben im Dateisystem unterscheiden.

CSS eines Plug-ins

Oft ist es erforderlich, zusammen mit einem Plug-in CSS-Regeln auszuliefern. Natürlich ist es möglich, sie innerhalb des JavaScript-Quelltexts unterzubringen und dynamisch auf die jeweiligen Elemente anzuwenden. Es ist jedoch meist sinnvoller, diese Regeln innerhalb einer getrennten Datei zu speichern. Das erhöht nicht nur die Lesbarkeit des Quelltexts, sondern erleichtert auch spätere Anpassungen durch den Anwender des Plug-ins.

CSS-Dateien, die zu einem speziellen Plug-in gehören, sollten den Dateinamen jquery.[Pluginname].css tragen. In diesem Beispiel ist das jquery.myPlugin.css. Auch hier gilt der Grundsatz, lediglich Kleinbuchstaben zu verwenden.

Weitere Dateien eines Plug-ins

Gelegentlich benötigt ein Plug-in neben JavaScript-Quelltext und CSS-Regeln noch weitere Dateien. Das können z. B. Bilder, Videodateien, oder jegliche andere Art von Daten sein. Für sie existiert kein konkretes Namensschema, da dieser Fall nur selten auftritt. Hier bleibt die Auswahl geeigneter Dateinamen Ihnen als Entwickler überlassen. Für den Autor haben sich zwei unterschiedliche Ansätze als praktikabel erwiesen:

Die erste Variante ist die Ablage der entsprechenden Dateien in Ordnern, die ihren Inhalt beschreiben. Bilder würden sich somit im Verzeichnis images wiederfinden, wohingegen Videos im Ordner videos residierten. Weil diese Ordner natürlich in größeren Applikationen nicht nur von einem Plug-in, sondern mehreren verwendet würden, sollte der Plug-in-Name als Präfix innerhalb des Dateinamens eingesetzt werden. Im konkreten Beispiel wäre z. B. die Grafik einer „Schließen“-Schaltfläche des hier skizzierten MyPlugins in der Datei images/myPlugin-close.png abgelegt.

Die zweite Variante ist die Unterbringung aller weiteren Dateien in einem Ordner mit dem Namen jquery.[Pluginname]. Im Fall dieses konkreten Beispiels: jquery.myPlugin. Auch hier bietet es sich an, die einzelnen Dateien nach Inhalt zu gruppieren. Also jquery.myPlugin/images/close.png oder jquery.myPlugin/videos/warning.mp4. Auf ein weiteres Präfix im Dateinamen kann bei dieser Umsetzung natürlich verzichtet werden.

Egal, welche der beiden Methoden Sie präferieren, es empfiehlt sich immer, dem Anwender zu ermöglichen, den Speicherort und Dateinamen mittels einer Option zu verändern. Somit kann beim Einsatz des Plug-ins der Ablageort der „Schließen“-Schaltfläche einfach verändert oder sogar die Grafik vollständig ausgetauscht werden. Wie Sie diese Optionen umsetzen und behandeln können, lernen Sie in Kapitel 5.3.

Zugriff auf die jQuery-Bibliothek

Innerhalb eines Plug-ins wird für gewöhnlich Zugriff auf Funktionen der jQuery-Bibliothek benötigt. Wäre das nicht der Fall, käme die Frage auf, warum ein jQuery-Plug-in als Lösungsweg gewählt wurde.

Innerhalb von Plug-in-Quelltexten sollten Bibliotheksfunktionen nur unter Verwendung des jQuery-Objekts aufgerufen werden. Die Verwendung von Shortcuts wie dem $‑Objekt ist gänzlich zu unterlassen.

Die Begründung für diese Einschränkung liegt in der Fähigkeit von jQuery, parallel zu weiteren JavaScript-Bibliotheken innerhalb einer Webseite zu koexistieren. Um das zu erreichen, kann auf dem jQuery-Objekt die Funktion noConflict aufgerufen werden, die sicherstellt, dass eventuelle Belegungen des $‑Shortcuts durch andere Bibliotheken weiterhin Gültigkeit besitzen. Nach dem Aufruf dieser Methode ist ein Zugriff auf jQuery nur noch über das jQuery-Objekt direkt oder einen vom Benutzer festgelegten anderen Bezeichner möglich. Ein Plug-in kann sich also nicht auf die Existenz des $‑Objekts verlassen.

Hinweis

Viele verschiedene JavaScript-Bibliotheken haben das Dollarzeichen ($) als Bezeichner ausgewählt. Diese Entscheidung liegt nahe, da das $-Zeichen innerhalb von JavaScript keine besondere Bedeutung besitzt, optisch gut zu erkennen ist und sich leicht eingeben lässt. Außerdem ist bei häufig wiederkehrenden Aufrufen, wie z. B. der Selektion von DOM-Elementen, eine möglichst kurze Zeichenkette wünschenswert. Auch wenn die Verwendung dieses Symbols vollkommen plausibel ist, so haben einige Bibliotheken den gravierenden Nachteil, dass Sie dieses nicht als zusätzlichen Shortcut anbieten, sondern als alleinige Zugriffsmöglichkeit auf deren Funktionalität. Um dieses Manko anderer Bibliotheken zu kompensieren, existiert in jQuery die noConflict-Funktion.

$-Shortcut dennoch einsetzen

Sind die Gründe für den Einsatz des jQuery-Objekts anstelle des $-Shortcuts bekannt, lässt sich mit diesem Wissen ein Ausweg aus dem Dilemma finden, der die Verwendung des $-Symbols auch innerhalb eines jQuery-Plug-ins ermöglicht, ohne dabei dessen Integrität zu gefährden.

Um die Wirkungsweise dieses Tricks zu verstehen, muss zunächst eine Eigenschaft von JavaScript selbst erläutert werden: Lambda-Funktionen.

JavaScript erlaubt die Definition sog. Lambda- oder anonymer Funktionen. Hierbei handelt es sich um Funktionen, die nicht mit einem konkreten Namen versehen werden. Stattdessen können sie in einer Variablen gespeichert oder direkt zur Ausführung gebracht werden. Die Deklaration entspricht der einer üblichen Funktion, jedoch ohne Angabe eines Namens. Listing 4.1 zeigt die Erzeugung einer solchen Lambda-Funktion und deren anschließende Speicherung in der Variablen fn.

var fn = function() {
  // Hier befindet sich der übliche Funktionsrumpf
};

Wie zuvor erwähnt, ist nicht nur die Speicherung in einer Variablen möglich, sondern außerdem die direkte Ausführung (Listing 4.2).

(function() {
  // Hier befindet sich der übliche Funktionsrumpf
})();

Um eine Lambda-Funktion direkt nach ihrer Deklaration zur Ausführung zu bringen, wird sie in runde Klammern eingeschlossen und dieses Konstrukt genau wie jede andere Funktion mittels Argumentenübergabe aufgerufen. Existieren wie im Beispiel aus Listing 4.2 keinerlei Funktionsargumente, erfolgt der Aufruf in gewohnter Weise durch ein leeres Klammernpaar.

Hinweis

Lambda-Funktionen sind Ihnen bereits innerhalb der jQuery-Einführungskapitel über den Weg gelaufen. Anonyme Funktionen eigenen sich für die verschiedensten Anwendungsgebiete und werden daher in JavaScript sehr häufig zum Einsatz gebracht. Sie werden diesem Konstrukt also noch häufiger begegnen.

Mit diesem Wissen um Lambda-Funktionen ist es nun möglich, den $-Shortcut gefahrlos während der Plug-in-Entwicklung einzusetzen. Der gesamte Plug-in-Quelltext wird hierzu in einer Lambda-Funktion eingeschlossen, die ein Argument mit dem Bezeichner $ entgegennimmt. Bei dem unmittelbar darauf folgenden Aufruf der Funktion wird als Inhalt für eben dieses Argument das jQuery-Objekt übergeben. Da der Zugriff auf Variablen immer zunächst im aktuellen Scope erfolgt und jede Funktion einen eigenen Scope besitzt, führt ein Aufruf des $-Shortcuts innerhalb des Plug-in-Quelltexts nun unweigerlich zum jQuery-Objekt, unabhängig von seiner Belegung außerhalb der Funktion (Listing 4.3).

(function($) {
  // Hier befindet sich der komplette Plug-in-Quelltext.
  // Ein Zugriff auf $ innerhalb dieser Funktion führt immer 
  // zum jQuery-Objekt.
})(jQuery);

Profitipp

Der Zugriff auf jegliche Art von Bezeichner in JavaScript (Variablennamen, Funktionen, …) erfolgt immer zunächst im lokalen Scope. Wird der jeweilige Bezeichner in diesem Scope nicht gefunden, wird die Suche im nächsthöheren fortgesetzt. Erst wenn der äußerste Scope erreicht und dort der Bezeichner nicht gefunden wurde, gilt er als nicht verfügbar. Für jede Funktion, egal ob anonym oder nicht, erstellen JavaScript Engines einen neuen Ausführungskontext und somit einen neuen Scope. Generell gilt die Regel: Der Zugriff auf Bezeichner aus dem lokalen Scope ist schnell, wohingegen jede weitere Ebene nach außen den Zugriff verlangsamt. Aus diesem Grund sollte es vermieden werden, Bezeichner anzufordern, die nicht im lokalen Scope liegen. Ist ein mehrfacher Zugriff auf diese Bezeichner erforderlich, bietet es sich an, sie in einer Variablen innerhalb des lokalen Scopes abzulegen und von dort aus zu benutzen. Auch wenn aktuelle JavaScript Engines durch diverse Optimierungen versuchen, dieses Problem zu minimieren, ist es dennoch sinnvoll, sich dieser Tatsache bewusst zu sein. Bezogen auf Listing 4.3 bedeutet das also, dass ein Zugriff auf $ innerhalb der Funktion schneller ist als ein Zugriff auf jQuery selbst, da dieser Bezeichner nicht im lokalen Scope der Funktion liegt.

Aufmacherbild: electric plug icon von Shutterstock / Urheberrecht: zerotwo foto

[header = Lambda-Funktionen nicht nur für den $-Shortcut]

Lambda-Funktionen nicht nur für den $-Shortcut

Es ist nützlich, ein jQuery-Plug-in innerhalb einer Lambda-Funktion einzuschließen, egal ob der $-Shortcut eingesetzt werden soll oder nicht. Der Hauptgrund ist der zuvor bereits angesprochene neue Scope, der für diese Funktion erzeugt wird. Durch diese Gegebenheit ist garantiert, dass sämtliche innerhalb des Plug-ins deklarierten Bezeichner, also Variablen und Funktionen, innerhalb des Plug-in-Kontexts verbleiben und nicht den globalen Namensraum verschmutzen. Außerdem ist es so möglich, innerhalb des Plug-ins private Funktionen zu definieren, die nicht von außen zugreifbar sind.

Anlegen neuer Set-Methoden

Da das Erweitern von jQuery-Sets mit neuen Methoden, wie bereits in der Vorstellung der einzelnen Plug-in-Typen erwähnt, eines der wichtigsten und am häufigsten anzutreffenden Einsatzgebiete von Plug-ins ist, fällt das in den Bereich der Grundregeln der Plug-in-Entwicklung.

Neue Methoden eines jQuery-Sets müssen innerhalb des jQuery.fn-Namensraums definiert werden. Innerhalb dieses Objekts tragen sie den gleichen Namen, mit dem sie fortan auf beliebigen Sets aufgerufen werden können. Es ist üblich, den Namen des Plug-ins und der Methode aufeinander abzustimmen.

Zur Erstellung einer solchen Methode wird erneut zur Lambda-Funktion gegriffen. Für das hier beispielhaft benannte Plug-in MyPlug-in kann die Deklaration der gleichnamigen Set-Methode in Listing 4.4 nachvollzogen werden.

jQuery.fn.myPlug-in = function() {
  // Inhalt der neuen Methode
};

Wie bei allen auf jQuery-Sets verfügbaren Methoden ist es üblich, den Namen mit einem Kleinbuchstaben zu beginnen und einzelne Worte durch CamelCase-Schreibweise abzugrenzen.

Während diese neue Methode auf einem Set aufgerufen wird, ist es möglich, durch die Variable this auf das Set des Aufrufs Zugriff zu nehmen. In Kapitel 5 wird durch die praktische Anwendung dieser und aller bisherigen Regeln dieses Konzept verdeutlicht.

Anlegen neuer Funktionen

Neben dem Erzeugen neuer Methoden für Sets ist die Definition von neuen Funktionen ein weiterer Kernbereich für den Einsatz von Plug-ins.

Neue Funktionen, die unabhängig von Sets agieren, werden direkt auf dem jQuery-Objekt registriert.

Auch hier gilt für die Namensgebung wie bei Set-Methoden die unausgesprochene Regel, sie dem Plug-in-Namen anzupassen und in CamelCase-Schreibweise mit beginnendem Kleinbuchstaben auszuführen (Listing 4.5).

jQuery.myPlug-in = function() {
  // Hier befindet sich der Rumpf der Set unabhängigen Funktion.
};

Beachtung des Fluent-Interface

Wie Sie sich aus dem Einführungskapitel sicherlich noch erinnern, unterstützt jQuery für die meisten seiner Methoden das Konzept des sog. Fluent-Interfaces. Kurz gesagt bedeutet das: Jede Methode liefert als Rückgabewert ihr Eingabeset. Durch diesen Trick ist es möglich, den Aufruf mehrerer Methoden direkt aneinanderzureihen. Natürlich soll diese Eigenschaft auch für Methoden aus der Eigenentwicklung gelten, um dem Bedienungsgrundsatz der übrigen Bibliothek zu genügen.

Eine Methode auf einem jQuery-Set sollte immer das aktuelle Set als Rückgabewert liefern, es sei denn, besondere Umstände erzwingen einen anderen Wert.

Wie bereits angesprochen, ist das aktuelle Set beim Aufruf einer entsprechenden Methode über den Bezeichner this erreichbar. Es genügt zur Umsetzung dieser Regel, den Inhalt eben dieser Variablen als Rückgabewert einzusetzen (Listing 4.6).

Hinweis

In Bezug auf die Regel bedeuten „besondere Umstände“, dass es die vornehmliche Funktion der neuen Methode ist, einen anderen Wert als das Set zurückzugeben. Als Beispiel eignen sich hier z. B. die Methoden height und width, die ohne übergebenes Argument die Größe eines Elements bestimmen und sie zurückgeben. In solch speziellen Fällen darf die Kette des Fluent-Interface natürlich durchbrochen werden. Wird jedoch ein anderer Wert als Rückgabe eingesetzt, muss das in jedem Fall deutlich dokumentiert werden.

jQuery.fn.myPlug-in = function() {
  // Der Plug-in-Quelltext steht hier
  return this;
};

Multiple Elemente eines Sets korrekt behandeln

Während der Entwicklung von Methoden muss immer bedacht werden, dass sie auf Sets agieren, die möglicherweise mehr als ein Element beinhalten. jQuery besitzt mit der each-Methode eine einfache Möglichkeit, dieses Faktum zu berücksichtigen und korrekt zu behandeln. Auch wenn hierzu Ausnahmen existieren, ist es meistens sinnvoll, die Aufgabe des Plug-ins separat auf jedes Element eines Sets anzuwenden. In diesen Fällen ist der Einsatz von each die richtige Wahl.

Die each-Methode sollte eingesetzt werden, um alle Elemente des Ausgangssets korrekt zu behandeln.

Die each-Methode und das Fluent-Interface

Natürlich darf im Kontext von each nicht das Fluent-Interface vergessen werden. Da sich diese Methode selbst an das Paradigma hält, kann dessen Rückgabewert bequem durchgereicht werden (Listing 4.7).

jQuery.fn.myPlug-in = function() {
  return this.each( function() {
    // this ist in diesem Kontext nur noch ein einzelnes Element
  } );
};

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -