Seiten

Sonntag, 1. Juni 2014

JavaScript: Das eigene jQuery Plugin

jQuery Plugin
Natürlich existiert dieser Blog nicht nur zum Spaß - oh nein - wir wollen ja auch etwas lernen. Darum hab ich mir überlegt, ein kleines Tutorial zu verfassen, wie man sich sein eigenes jQuery Plugin programmieren kann. Egal ob privat, beruflich oder einfach nur... zum Spaß...

Zunächst einmal möchte ich aber auf das "offizielle" Plugin-Tutorial der jQuery Foundation hinweisen. Ich werde aber versuchen, das ganze in einfachen - und vor allem in eigenen Worten - zu beschreiben.

Hinweis: Grundlegende HTML und JavaScript Kenntnisse wären ganz hilfreich, aber nicht unbedingt notwendig.

1. Die Vorbereitung


Als erstes benötigen wir eine einfache HTML Datei index.html. Hier reicht zu Beginn wirklich nur der Minimalaufbau. Natürlich legen wir das Ganze gleich im HTML5 Markup an.

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
  </body>
</html>

Da wir ein jQuery Plugin bauen wollen, muss selbstverständlich die jQuery Bibliothek in unsere Datei eingebunden werden. Ich empfehle hier die Datei aus den Google Hosted Libraries. Das erspart ein lästiges Herunter- und Hochladen.

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/x.x.x/jquery.min.js"></script>

Und mit diesen Grundlagen, können wir auch schon beginnen.

2. Das HTML-Gerüst


Mit unserem Plugin möchten wir in einen bestimmten div Container ein canvas Element einbauen und es mit individuellen Attributen wie ID, Breite und Höhe versehen.
Hier sei zunächst gesagt, dass man all das auch wesentlich einfacher direkt im HTML definieren kann, aber hier geht es ja schließlich um den Lerneffekt.

Dazu legen wir uns eine leere Datei jquery.canvasation.js an und bauen sie in unseren head der HTML Datei ein. Natürlich nach der jQuery Bibliothek.
Auch definieren wir gleich den div Container, in den später unser canvas Element geschrieben wird. Dieser Container benötigt eine bestimmte ID, über die ihn das JavaScript, und damit das Plugin, ansprechen kann.

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/x.x.x/jquery.min.js"></script>
    <script type="text/javascript" src="jquery.canvasation.js"></script>
  </head>
  <body>
    <div id="canvasContainer"></div>
  </body>
</html>

Und damit wäre das HTML-Gerüst für's Erste auch schon fertig. Also widmen wir uns nun dem JavaScript und dem eigentlichen Programmieren des Plugins.

3. Die Objekt Methode


Unser Plugin ist letztendlich nichts anderes, als eine - von uns festgelegte - Objekt Methode, um die wir die jQuery Bibliothek erweitern wollen. Und diese Methode müssen wir jQuery irgendwie beibringen.
Dazu nutzen wir das $.fn Objekt, in dem sozusagen alle Objekt Methoden gespeichert sind. Dieses lässt sich gleichsetzen mit $.prototype und erlaubt uns, hier eine eigene Methode zu definieren, damit wir sie beliebig einsetzen können
Um das anschaulich zu machen, hier ein einfaches Beispiel:

$.fn.canvasation = function()
{
  this.append('<canvas id="canvasation" width="100" height="100"></canvas');
};

Hier erweitern wir nun also das $.fn Objekt um die Methode .canvasation(). Und diese soll nichts anderes tun, als unserem gewählten Selektor, über die .append() Methode, ein canvas Element anzuhängen, mit der ID #cavasation und jeweils einer Höhe und Breite von 100 Pixeln.
Dazu müssen wir diese Methode allerdings noch in unserer HTML Datei aufrufen.

<script type="text/javascript">
  $('#canvasContainer').canvasation();
</script>

Damit wenden wir auf unseren Selektor, unseren div Container mit der ID #canvasContainer, die Methode .canvasation() an.

4. Der $-Alias


Beinahe alle JavaScript Bibliotheken nutzen die bekannte $ Variable. Wenn wir also neben jQuery noch weitere Bibliotheken verwenden, werden wir auf einige Probleme stoßen, da sich die verschiedenen $ Variablen in die Quere kommen.
Dieses Problem könnten wir natürlich mit der jQuery.noConflict() Methode umgehen. Doch leider geht unser Plugin davon aus, dass die $ Variable ein Alias der jQuery Funktion ist und würde daher nicht mehr funktionieren.
Die Lösung des Problems ist also, unsere Funktion in eine Immediately Invoked Function zu verpacken.

(function($)
{
  $.fn.canvasation = function()
  {
    this.append('<canvas id="canvasation" width="100" height="100"></canvas');
  };
})(jQuery);

Wie der Name schon sagt wird eine Immediately Invoked Function sofort nach ihrer Generierung ausgeführt. Das erlaubt uns $ als Funktionsparameter zu definieren und ihm bei der sofortigen Ausführung den Wert jQuery zu übergeben.

5. Die Optionen


Im Prinzip wäre unser Plugin jetzt fertig. Denn es generiert ein canvas Element in einem div Container. Aber da das bisher noch nicht sehr spannend (und auch nicht sonderlich nützlich) ist, wollen wir noch einen Schritt weiter gehen und es konfigurierbar machen. Wir möchten also beim Aufruf des Plugins Optionen übergeben, die dann verarbeitet und angewendet werden.

Der einfachste Weg dies zu ermöglichen, ist mit Hilfe von zwei Object Literals (was sich in etwa mit "tatsächliches Objekt" übersetzen lässt) und der .extend() Methode.
Ein Object Literal ist hierbei nichts anderes, als eine kommaseparierte Sammlung von beliebigen Werten, die beliebigen Namen zugewiesen wurden. Und davon benötigen wir eines, in dem die Default Werte gespeichert werden und eines, in dem wir später unsere eigenen Werte übergeben können. Mittels der .extend() Methode können wir dabei beide Objekte zusammenfügen und das erste Object Literal durch das zweite überschreiben lassen.
Um das anschaulich zu machen, hier ein einfaches Beispiel:

(function($)
{
  $.fn.canvasation = function(options)
  {
    var settings = $.extend(
    {
      canvasID     : 'canvasation',
      canvasWidth  : '100',
      canvasHeight : '100'
    }, options);

    this.append('<canvas id="' + settings.canvasID + '" width="' + settings.canvasWidth + '" height="' + settings.canvasHeight + '"></canvas');
  };
})(jQuery);

Wir erweitern unsere .canvasation() Methode nun also um den Funktionsparameter options und die Variable settings. In dieser Variable werden die beiden Object Literals über die .extend() Methode zusammengefügt.
Im ersten Object Literal legen wir die Default Optionen an, in dem wir - wie schon erwähnt - die Default Werte den von uns festgelegten Namen zuweisen. Zum Beispiel erhält canvasWidth den Wert 100.
Das zweite Object Literal wird später beim Aufruf der .canvasation() Methode über den options Parameter übergeben und überschreibt, wenn nötig, die Werte des ersten.

Die letztendlichen Werte werden dann in den HTML Code der .append() Methode eingefügt, indem wir zuerst die Variable settings und darin wiederum den Inhalt von canvasWidth auslesen.

6. Der Aufruf


Bei Punkt 3 haben wir bereits gelernt, wie wir das Plugin in unserer HTML Datei aufrufen.
Würden wir das jetzt weiterhin so tun, so würden die Default Werte unseres festgelegten Object Literals verwendet werden. Um diese nun mit unseren eigenen Werten zu überschreiben, müssen wir in unserem Plugin-Aufruf ebenfalls ein Object Literal festlegen.

<script type="text/javascript">
  $('#canvasContainer').canvasation(
  {
    canvasID     : 'webwahnsinn',
    canvasWidth  : '300',
    canvasHeight : '600'
  });
</script>

Hier verwenden wir nun einfach dieselben Namen, wie schon in unserer .canvasation() Methode und weisen ihnen unsere benutzerspezifischen Werte zu.

7. Das Fazit


Und das war es auch schon. Damit haben wir unser erstes eigens jQuery Plugin geschrieben.
Wir haben damit ein Plugin, das ein canvas Element in einen div Container schreibt, das wir mit unseren eignen Attributen ausstatten können.
Das hat im "richtigen Leben" natürlich keinerlei Sinn, da man es - wie eingangs schon erwähnt - im HTML wesentlich schneller und einfacher definieren kann, aber ich hoffe ihr habt trotzdem etwas gelernt.
Und sobald ich eine Idee für ein sinnvolles jQuery Plugin habe, gibt es dazu natürlich auch ein Tutorial.

Zum Schluss gibt es hier jetzt nochmals den kompletten Code an einem Stück:

//jquery.canvasation.js

(function($)
{
  $.fn.canvasation = function(options)
  {
    var settings = $.extend(
    {
      canvasID     : 'canvasation',
      canvasWidth  : '100',
      canvasHeight : '100'
    }, options);

    this.append('<canvas id="' + settings.canvasID + '" width="' + settings.canvasWidth + '" height="' + settings.canvasHeight + '"></canvas');
  };
})(jQuery);

//index.html

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/x.x.x/jquery.min.js"></script>
    <script type="text/javascript" src="jquery.canvasation.js"></script>
  </head>
  <body>
    <div id="canvasContainer"></div>

    <script type="text/javascript">
      $('#canvasContainer').canvasation(
      {
        canvasID     : 'webwahnsinn',
        canvasWidth  : '300',
        canvasHeight : '600'
      });
    </script>
  </body>
</html>