Nun der zweite Teil des JavaScripts.
Wir haben bereits unser FaderFramework-Objekt erstellt und auch schon initialisiert. Außerdem haben wir uns schon festgelegt, wie wir das Einrichten eines Faders gerne gestalten möchten. Dazu schauen wir nocheinmal in unsere HTML-Datei:
FaderFramework.init({
id: "fader_test_2",
images: ["images/sonne1.jpg", "images/sonne2.jpg", "images/sonne3.jpg", "images/sonne4.jpg"]
});
Wir brauchen also eine Funktion "init", die unsere Einstellungen als Objekt (man beachte die geschweiften Klammern innerhalb des Funktionsaufrufs - Objektliteral!) entgegennimmt. In diesem Objekt (es ist im Prinzip ein anonymes Objekt) vergeben wir Eigenschaften (z.B. "id" oder "images"), die wir mit unseren Werten füllen. "id" nennt dabei die ID des <img />-Elements und "images" enthält ein Array mit Zeichenketten, die (von unserer HTML-Datei aus, es wären aber auch absolute Angaben möglich) den Pfad zu den Bilddateien darstellen.
Unsere init-Funktion wird aber schon während des Ladevorgangs ausgeführt, also zu einem Zeitpunkt, zu dem entweder noch kein <body>-Element existiert, oder aber irgendwie das HTML-Dokument noch unvollständig ist. Daher kann unsere init-Funktion keinen Fader einrichten! Sie kann aber diese Aufgabe zumindest vermerken, und das tut sie, indem sie alle Aufrufe in einer weiteren Eigenschaft unseres FaderFramework-Objektes ablegt: "inits".
Um etwas Komfort in unser Script zu bringen, bieten wir einige Einstellungen an, die später unser Script dann umsetzen wird. Details dazu folgen in einem anderen Teil.
init: function (einstellungen) {
/* "einstellungen" ist ein Objekt, das folgende Struktur haben muss:
{
id: "id_des_HTML_Elements", // muss einmalig sein!!
images: ["pfad/bild1.jpg", "pfad/bild2.jpg"], // mindestens zwei Bilder, da ansonsten sinnlos!
viewTime: 20000, // optional -> Voreinstellung ist 5000
fadeStep: 1, // optional -> Voreinstellung ist 0.5
random: true, // optional -> Voreinstellung ist "false"
autostart: false // optional -> Voreinstellung ist "true"
}
*/
this.inits[this.inits.length] = einstellungen; // für später abspeichern
},
Nun müssen wir uns der onload-Funktion widmen, denn es warten einige Aufgaben auf sie.
1.) spezielle CSS-Datei einbinden 2.) die "bestellten" (also per init() eingerichteten) Fader tatsächlich erstellen und ausrüsten
Zu diesen Aufgaben ein paar Gedanken:
Um weitere zu diesem Projekt gehörende Dateien einbinden (oder irgendwie referenzieren) zu können, müssen wir wissen, in welchem Verzeichnis sich unser Script befindet. Wenn wir diese Information ermittelt haben, sollten wir sie zentral speichern. Zu diesem Zweck benutzen wir daher eine weitere Eigenschaft des FaderFramework-Objektes namens "baseURL", die das Verzeichnis unserer JavaScript-Datei enthalten soll. Damit können wir dann auch unsere CSS-Datei aus demselben Verzeichnis einbinden.
Bei anderen Projekten kann es sinnvoll sein, die CSS-Datei(en) in einem extra Unterordner (sinnigerweise namens "css") bereitzuhalten, vor allem dann, wenn zu der JavaScript-Applikation noch weitere Dateien (z.B. Bilder, HTML-Dokumente etc.) gehören sollten.
Um Fader zu erstellen, entwickeln wir eine Art Schablone, die in diesem Teil aber noch nicht besprochen wird. Wichtig ist nur, dass diese Funktion (genauer: Konstruktorfunktion) uns entweder ein Objekt mit dem Fader zurückgibt, oder aber den Wert false (wenn die Erstellung scheitert).
Da jeder Fader anhand eines <img />-Elements mit einer einmaligen ID erstellt wird, benutzen wir diese ID einfach, um diesen Fader dann in unserem Framework abzulegen. Auch dazu brauchen wir wieder eine weitere Eigenschaft unseres FaderFramework-Objektes - nennen wir sie "faders" - zum Ablegen. Diesmal ist es aber kein Array, da die Unterobjekte in dieser Eigenschaft ja "benannt" werden sollen. Warum sie das sollen, wird in einem nächsten Teil behandelt werden.
Nun zum Code unserer onload-Funktion:
onload: function () {
/* "this" verweist auf unser FaderFramework-Objekt! */
var scripts, i, fader, css;
// baseURL herausfinden, um weitere Komponenten dieses Scripts nachladen zu können
scripts = document.getElementsByTagName("script");
for (i = 0; i < scripts.length; i++) {
// alle <script>-Elemente durchsuchen, ob sie ein passendes src-Attribut haben
if (scripts[i].src && scripts[i].src.match(/fader-framework\.js$/)) {
fader = scripts[i];
}
}
// fader muss eigentlich gefunden worden sein, es sei denn der Dateiname wurde geändert...
if (fader) {
this.baseURL = fader.src.replace(/(.*)\/[^\/]+$/, "$1");
}
// weitere Komponenten einbinden wenn baseURL ermittelt wurde
if (this.baseURL) {
// unsere CSS-Datei einbinden (also <link rel="stylesheet" type="text/css" href="..." /> erzeugen)
css = document.createElement("link");
css.rel = "stylesheet";
css.type = "text/css";
css.href = this.baseURL + "/fader-framework.css";
// <link />-Element im <head> hinten anfügen
document.getElementsByTagName("head")[0].appendChild(css);
}
// zu initialisierende Fader einrichten
for (i = 0; i < this.inits.length; i++) {
// Fader erstellen lassen
fader = new this.Fader(this.inits[i]); // this.Fader ist eine Konstruktor-Funktion!
// abspeichern wenn Fader erfolgreich erstellt wurde
if (fader) {
this.faders[fader.id] = fader;
if (fader.autostart) {
// Fader autostarten
fader.start(); // start() wird dem Fader in der Konstruktor-Funktion verliehen
}
}
}
},
Mit allen unseren Überlegungen und Funktionen sieht unser FaderFramework nun so aus:
var FaderFramework = {
// "Einstellungen"
className: "fader", // die Klasse, die unser Element trägt, in dem die Bilder sitzen sollen
// Voreinstellungen für einen Fader
viewTime: 5000, // Zeit, die ein Bild angezeigt wird (in Millisekunden)
fadeStep: 0.5, // Prozent-Schritt beim Überblenden
random: false, // Zufällige Reihenfolge der Bilder (true|false)
autostart: true, // sofort mit dem Fading starten (true|false)
// automatische Einstellungen
baseURL: "", // hier steht später der Pfad zum Verzeichnis, in dem sich dieses Script befindet.
oldWinOnLoad: false, // hier steht später vielleicht eine abgespeicherte Funktion
inits: new Array(), // hier stehen später auszuführende Initialisierungen
faders: new Object(), // hier werden die Fader stehen
// Initialisier-Funktion - startet das FaderFramework indem sie das onload-Verhalten im Dokument regelt (wird noch während des Ladens der Seite ausgeführt)
start: function () {
this.oldWinOnLoad = window.onload; // alte onload-Funktion abspeichern (falls vorhanden)
// neue (anonyme!) onload-Funktion erstellen um eventuelle alte Funktion(en) zu kapseln
window.onload = function () {
// War bereits eine Funktion in window.onload abgelegt worden?
if (typeof(FaderFramework.oldWinOnLoad) == "function") {
// hier kann man nicht "this" benutzen, da diese Funktion nicht zu einem größeren Objekt gehört!
FaderFramework.oldWinOnLoad(); // gespeicherte onload-Funktion ausführen
}
FaderFramework.onload(); // unsere onload-Funktion ausführen
};
},
// onload-Funktion wird unmittelbar nach dem vollständigen Laden des Dokuments ausgeführt
onload: function () {
/* "this" verweist auf unser FaderFramework-Objekt! */
var scripts, i, fader, css;
// baseURL herausfinden, um weitere Komponenten dieses Scripts nachladen zu können
scripts = document.getElementsByTagName("script");
for (i = 0; i < scripts.length; i++) {
if (scripts[i].src && scripts[i].src.match(/fader-framework\.js$/)) {
fader = scripts[i];
}
}
// fader muss eigentlich gefunden worden sein, es sei denn der Dateiname wurde geändert...
if (fader) {
this.baseURL = fader.src.replace(/(.*)\/[^\/]+$/, "$1");
}
// weitere Komponenten einbinden wenn baseURL ermittelt wurde
if (this.baseURL) {
// unsere CSS-Datei einbinden (also <link rel="stylesheet" type="text/css" href="..." /> erzeugen)
css = document.createElement("link");
css.rel = "stylesheet";
css.type = "text/css";
css.href = this.baseURL + "/fader-framework.css";
// <link />-Element im <head> hinten anfügen
document.getElementsByTagName("head")[0].appendChild(css);
}
// zu initialisierende Fader einrichten
for (i = 0; i < this.inits.length; i++) {
// Fader erstellen lassen
fader = new this.Fader(this.inits[i]); // this.Fader ist eine Konstruktor-Funktion!
// abspeichern wenn Fader erfolgreich erstellt wurde
if (fader) {
this.faders[fader.id] = fader;
if (fader.autostart) {
// Fader autostarten
fader.start(); // start() wird dem Fader in der Konstruktor-Funktion verliehen
}
}
}
},
// Funktion zum Einrichten eines Faders (wird noch während des Ladens der Seite ausgeführt - eventuell mehrmals)
init: function (einstellungen) {
/* "einstellungen" ist ein Objekt, das folgende Struktur haben muss:
{
id: "id-des-HTML-Elements", // muss einmalig sein!!
images: ["pfad/bild1.jpg", "pfad/bild2.jpg"], // weitere Bilder möglich
viewTime: 20000, // optional -> Voreinstellung ist 5000
fadeStep: 1, // optional -> Voreinstellung ist 0.5
random: true, // optional -> Voreinstellung ist "false"
autostart: false // optional -> Voreinstellung ist "true"
}
*/
this.inits[this.inits.length] = einstellungen; // für später abspeichern
}
}
FaderFramework.start();
Jetzt fehlt uns noch der eigentlich komplexeste Brocken: Die Konstruktor-Funktion für einen Fader. Die gibt es aber erst im nächsten Teil.
War dieser Teil nachvollziehbar? Verständlich? Vom Konzept her logisch aufgebaut?
Liebe Grüße,
Felix Riesterer.
ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)