Dieser Beitrag stammt aus meinem alten Blog. Da ich sehr viel positives Feedback auf diesen bekommen habe stelle ich ihn hier wieder zur Verfügung.
Wenn man, wie ich, viel mit jQuery arbeitet gibt es immer wieder Funktionen die man häufiger braucht und daher natürlich auch gerne wieder verwenden würde. An einem sehr einfachen Beispiel möchte ich Euch daher mal zeigen, wie man ein eigenes jQuery Plug-In schreibt.
Der Ansatz ist hier ein sehr einfacher: Wir hätten gerne unter unseren Bildern einen Text zum Bild der über jQuery eingebunden werden soll. Unser erster Ansatz hier ist folgender:
- Um das Bild einen
div-Container setzen mit.wrap() - dann unter das Bild einen Absatz (
<p>) in dem der Inhalt desalt-Attributs steht
Umsetzen könnte man das u.a. so:
var alt = $('img.addCaption').attr("alt");$('img.addCaption').wrap('<div class="image"></div<').after('>p<');$('.image p').text(alt);
Wir gehen bei diesem sehr einfachen Beispiel davon aus das wir nur ein Bild mit der Klasse .addCaption im HTML-Dokument haben und speichern zunächst dessen alt-Attribut in einer Variable var ab. In der zweiten Zeile des Codes umschliessen wir das Bild (.wrap()) mit einem div-Container mit der Klasse .image und fügen dann noch hinter dem Bild einen leeren Absatz ein (.after()).
In der dritten und letzten Zeile bekommt dann der Absatz innerhalb von div.image den in alt gespeicherten Text eingesetzt (.text()).
Dieser Code hat einige Nachteile: Er klappt nur bei einem Bild da er bei mehreren Bildern mit der Klasse .addCaption immer den Text des letzten alt-Attributs einfügen würde und wenn ich schon so eine Funktion einfüge muss diese auch alternative Texte anbieten können.
Viel von den fehlenden Bedingungen könnte ich auch ohne Plug-In machen aber darum geht es hier ja nicht.
Bevor wir unsere Funktion nun in ein Plug-In stecken und ein wenig erweitern schauen wir uns den Rahmen an:
$.fn.addCaption = function(options) {return this.each(function(){});};
In der ersten Zeile definieren wir unsere Funktion und geben ihr den Namen .addCaption(). Das Gerüst erklärt sich fast von selbst. Für Euch ist erstmal nur interessant das ihr mit $.fn.funktionsname =function(){} eine Funktion definiert die Ihr später wie die bekannten jQuery-Funktionen verwenden könnt. Auf options innerhalb der Funktion gehe ich weiter unten ein.
Sehr wichtig ist dann noch die zweite Zeile. Wir möchten ja, das unsere Funktion für beliebig viele Bilder verwendet werden kann und daher müssen wir, in unserem Fall für jedes einzelne Bild, ein eigenes Ergebnis liefern.
Dabei bedeutet return erstmal das die Funktion etwas zurückgibt (für die Programmierer unter Euch nix neues). Interessanter ist da der folgende Code (also das, das wir zurückgeben): this.each(function(){}) bezieht sich erstmal auf die ausgewählten Elemente. Genauer gesagt: this bezeichnet quasi alle ausgewählten Elemente die von unserer Funktion bearbeitet werden. Mit .each() geben wir an jedes einzelne Element bearbeiten zu wollen. hr könnt Euch das so vorstellen als ob der Browser im Hintergrund jedes einzelne Element nimmt und dann die Schritte mit diesem durchgeht die wir innerhalb von function(){} durchgehen.
Bevor es jetzt richtig losgeht noch eine Absicherung: Eigentlich sollte man $ nicht verwenden wenn man ein Plug-In schreibt da es hier durchaus Probleme mit anderen Bibliotheken geben kann. Ich persönlich habe mich aber an $ gewöhnt und möchte das auch in meinem Plug-In verwenden. Wenn es Euch ähnlich geht hilft Euch folgender Code der nur zum Ziel hat das sich $ auf jQuery bezieht. Wenn Ihr Euch die zwei Zeilen sparen wollt setzt an die Stelle von $ einfach jQuery:
(function($){$.fn.addCaption = function(options) {return this.each(function() {});};})(jQuery);
Nun wollen wir die Funktionalität aus unserem Code weiter oben erstmal in unser Plug-In einbauen. Schon jetzt ist unser Plug-In etwas besser da wir mit dem Plug-In gleich schon mehrere Bilder bearbeiten können.
(function($){$.fn.addCaption = function(options) {return this.each(function() {var obj = $(this);var capText = obj.attr('alt');obj.wrap('<div class="image">').after('<p>').next("p").text(capText);});};})(jQuery);
Neu ist erstmal die Zeile 4 in der wir einer Variable obj $(this) zuweisen. Das heisst nicht mehr als das wir mit obj nun das momentane Element auswählen können. Also statt $(this).funktion() klappt innerhalb der Schleife auch obj.funktion(). Demnach schreiben wir nun auch var capText = obj.attr('alt'); um den Wert des alt-Attributs zu speichern.
Der Rest ist analog zu unserem Beispiel. Herzlichen Glückwunsch unser Plug-In ist fertig … fast…
Wir haben bei Plug-Ins noch die Möglichkeit Optionen einzubauen um das Plug-In etwas anpassbarer zu machen. Schliesslich sollten Nutzer unserer Plug-Ins nicht selber am Plug-In schrauben müssen sondern möglichst einfach anpassen können. Bei diesem Beispiel werden wir zwei Dinge dynamischer machen: Die Klasse des umschliessenden div-Containers und den Text der unter einem Bild angezeigt wird, wenn kein alt-Attribut definiert wurde.
Innerhalb de Plug-Ins definieren wir nun erstmal Standardwerte für beide Optionen. Dafür nehmen wir die Variable defaults.
(function($){$.fn.addCaption = function(options) {var defaults = {wrapClass: 'image',altText: 'entweder ein leeres oder kein alt-Attribut verwendet'};return this.each(function() {var obj = $(this);var capText = obj.attr('alt');obj.wrap('<div class="image">').after('<p>').next("p").text(capText);});};})(jQuery);
Diese neuen Zeilen bringen noch nichts und erzeugen eigentlich nur ein Objekt defaults dessen Werte man nun verwenden könnte. So liefert defaults.wrapClass den String ‘image’. Wir benötigen diese Standardwerte für den Fall das der Nutzer selber keine Optionen angegeben hat (options) und müssen nun im nächsten Schritt den Wert von options durch die Werte von defaults ergänzen. jQuery bietet hierfür die Funktion .extend() mit der wir ein Objekt vervollständigen können. Wenn also ein Wert innerhalb von options nicht gesetzt wird nehmen wir hier den Wert aus defaults.
(function($){$.fn.addCaption = function(options) {var defaults = {wrapClass: 'image',altText: 'entweder ein leeres oder kein alt-Attribut verwendet'};var options = $.extend(defaults, options);return this.each(function() {var obj = $(this);var capText = obj.attr('alt');obj.wrap('<div class="image">').after('<p>').next("p").text(capText);});};})(jQuery);
Da wir nun einige Variablen haben (Klasse des div-Containers und der Text für ein leeres alt-Attribut) müssen diese noch in unserem Plug-In eingebaut werden:
(function($){$.fn.addCaption = function(options) {var defaults = {wrapClass: 'image',altText: 'entweder ein leeres oder kein alt-Attribut verwendet'};var options = $.extend(defaults, options);return this.each(function() {var obj = $(this);var capText = obj.attr('alt');if(capText == '') capText = options.altText;obj.wrap('<div class="'+options.wrapClass+'">').after('<p>').next("p").text(capText);});};})(jQuery);
In Zeile 11 wird die Länge des alt-Attributs abgefragt. Wenn dies leer ist wird als Bildunterschrift der Wert von options.altText (aus options oder defaults, je nachdem was der User möchte). Die Klasse des div-Containers setzen wir in Zeile 12 dynamisch ein.
So fertig ist ein kleines Plug-In. Der Aufruf funktioniert dann entweder über:
$("img").addCaption();
dann werden die Standardwerte genommen, oder über
$("img").addCaption({wrapClass='klassenname',altText='Ein anderer Text'});