Diesen Tipp in Originalversion zeigen.

Menü, externe Inhalte und Preloader

Da immer wieder Fragen nach diesen Themen aufkommen, hier ein Artikel für eine simple Menünavigation mit dynamisch nachladbaren Inhalten und externem Preloader.

Zunächst erstellen wir die nötigen Steuerelemente: Buttons für das Menü, einen leeren Container, der die Inhalte aufnimmt und den Preloader, der den Fortschritt mit einem Balken anzeigt.

Unser Button benötigt im Prinzip nur eine Fläche, die angeklickt werden kann und eine einzige Memberfunktion. Damit es aber zumindest ein wenig nach etwas aussieht, habe ich dem Button zwei Schlüsselbilder (für MouseOut und MouseOver) verpasst. Auf einer weiteren Ebene fügen wir ein dynamisches Textfeld für die Beschriftung ein, dem wir den Instanznamen "btext" geben.



Der Button bekommt zunächst Funktionen, um die Mausereignisse zu verarbeiten:

this.useHandCursor = false;

stop(); // Wichtig, damit der Button zunächst im ersten Frame stehen bleibt.

this.onRollOver = function() {
 gotoAndStop(2);
}

this.onRollOut = this.onReleaseOutside = function() {
 gotoAndStop(1);
}

Des Weiteren bekommt der Button eine Funktion, um die Beschriftung festzulegen und eine, die eine (noch zu schreibende) Funktion im übergeordneten Clip (in unserem Falle: _root) aufruft:

function setText(txt) {
 this.btext.text = txt; // Beschriftung setzen
}

this.onRelease = function() {
 _parent.setContent(this._name);
}

Die letze Funktion übergibt der Funktion setContent den Instanznamen des jeweiligen Buttons. Diese Funktion werden wir gleich auf der Hauptzeitleiste anlegen. Über eine Liste können wir hiermit jedem Instanznamen eine zu ladende Datei zuordnen und müssen nicht jeder Buttoninstanz einen eigenen Handler geben.

Wir erstellen nun einen neuen MC für den Preloader. Auf der ersten Ebene zeichnen wir einen horizontalen Balken, den wir wiederum in einen MC konvertieren - er wird uns als Fortschrittsanzeige dienen. Wir geben diesem Clip den Instanznamen "bar".



Wir fügen im Preloader-Clip eine neue Ebene (code) ein und implementieren die nötigen Funktionen zum dynamischen Laden der Inhalte:

this._visible = false; // Zunächst unsichtbar schalten

var isloaded = false; // Nichts geladen

var cur = 0; // geladene Bytes

var max = 0; // Gesamte Bytes

var percent = 0; // Prozent der geladenen Bytes

function loadContent(cont, filename) {
 isloaded = false; // Noch nichts geladen
 cont.loadMovie(filename); // Laden der Datei
 this.onEnterFrame = function() {
  cur = cont.getBytesLoaded(); // Geladene Bytes und
  max = cont.getBytesTotal(); // gesamte Bytes holen
  if (cur > 0) { // Wenn etwas geladen wurde:
   this._visible = true; // sind wir sichtbar,
   percent = cur * 100 / max; // berechnen die Prozente
   bar._xscale = percent; // und lassen den Balken wachsen
   if (cur >= max) { // Wenn alles geladen wurde     isloaded = true; // sagen wir Bescheid,
    this._visible = false; // verstecken uns
    delete this.onEnterFrame; // und machen Pause
   }
  }
 }
}

Wir benötigen vier Membervariablen: isloaded, cur, max und percent.

"isloaded" zeigt der Hauptroutine auf _root, ob der entsprechende Film komplett geladen wurde, die anderen drei geben uns Auskunft über den Ladefortschritt.

Unsere Funktion "loadContent" bekommt als Parameter den Container, in den geladen werden soll, und den Dateinamen übergeben. Zunächst wird "isloaded" auf false gesetzt, damit der neue Inhalt nicht eingeblendet wird, bevor alles geladen ist. Nun wird mit der Methode "loadMovie" die SWF-Datei in den Container geladen und eine onEnterFrame-Methode gestartet. Wir holen uns periodisch die geladenen und die zu ladenden Bytes.

Da ein paar Sekunden vergehen können, bis die Informationen über die Dateigröße zur Verfügung stehen, prüfen wir, ob schon Bytes geladen wurden [ if (cur > 0) ] - und nur dann blenden wir den Preloader ein und skalieren den Ladebalken.

In "percent" schreiben wir den Prozentwert und übergeben ihn der _xscale-Eigenschaft des Balkens.

Wenn der Film komplett geladen ist [ if (cur >= max) ], setzen wir "isloaded" auf true, um anzuzeigen, dass der neue Inhalt zur Verfügung steht. Dann blenden wir den Preloader aus und löschen die onEnterFrame-Methode.

Nun fügen wir die Elemente auf der Hauptzeitleiste zusammen und schreiben die Funktionen zum Anwählen und Anzeigen der Inhalte.

Wir erstellen auf _root vier Ebenen: container, menu, loader und code.

Auf die Ebene "container" setzen wir einen leeren MovieClip (-> neues Symbol), dem wir den Instanznamen "container" geben (Info: Ebenen, Instanzen und Objekte in der Bibliothek können identische Bezeichner haben, ohne dass Konflikte entstehen. Ich verwende das gerne, um auf einen Blick zu sehen, in welcher Ebene welche Symbole liegen).

Auf die Ebene "menu" ziehen wir einige Instanzen des MovieClips "button". Ich habe hier die Instanznamen "button1" - "button5" verwendet, da ich hier über das letzte Zeichen des Namens schnellen Zugriff auf die Nummer des gewünschten Inhaltes bekomme.

Auf der Ebene "loader" instanzieren wir unseren Preloader und geben ihm den Instanznamen "loader".



Nun benötigen wir noch einige Funktionen, die wir auf der Ebene "code" einfügen:

this.onEnterFrame = function() {
 // Festlegen der Beschriftungen der Buttons:
 button1.setText("Inhalt 1");
 button2.setText("Inhalt 2");
 button3.setText("Inhalt 3");
 button4.setText("Inhalt 4");
 button5.setText("Inhalt 5");
 delete this.onEnterFrame;
}

Hier werden zunächst die Beschriftungen der Buttons festgelegt. Da Funktionen in MovieClips noch nicht direkt nach onLoad zur Verfügung stehen, verwende ich eine onEnterFrame-Methode, die nur ein einziges Mal aufgerufen wird.

var currentContent = 0; // Aktueller Inhalt (0 = keiner)

Diese Variable speichert die Nummer des aktuellen Inhaltes. Anhand dieser Nummer können wir feststellen, ob ein neuer Inhalt geladen werden soll, ob ein angezeigter Inhalt zunächst ausgeblendet werden muss oder ob der aktuelle Inhalt noch einmal angewählt wurde (in diesem Fall blenden wir den Inhalt aus).

function setContent(bname) {
 var new_content = int(bname.substr(bname.length - 1, 1)); // Nummer holen
 if (new_content > 0 && new_content != current_content) {
  if (current_content != 0) {
   switchContent(new_content); // Inhalt wechseln
  } else {
   loadContent(new_content); // Inhalt direkt laden
  }
 } else {
  switchContent(0); // Inhalt ausblenden
  current_content = 0;
 }
}

Dies ist die Funktion, die von unseren Buttons aufgerufen wird. Sie bekommt den Instanznamen des jeweiligen Buttons übergeben.

Anhand dieses Namens (die Buttons sind ja durchnummeriert) holen wir uns die Nummer des gewählten Buttons. Wenn schon ein Inhalt angezeigt wird und der neue Inhalt nicht dem aktuellen entspricht, wechseln wir den Inhalt [ switchContent(new_content) ], wenn noch kein Inhalt sichtbar ist, laden wir einfach einen neuen, ohne den aktuellen auszublenden [ loadContent(new_content) ], in allen anderen Fällen (kein Inhalt gewählt oder neuer Inhalt = aktueller Inhalt) blenden wir den aktuellen Inhalt einfach aus und setzen "current_content" auf Null.

function switchContent(nc) {
 current_content = 0; // Auf Null setzen, damit neue Inhalte schnell angezeigt werden können
 this.onEnterFrame = function() {
  container._alpha += (0 - container._alpha) / 5; // Container ausblenden
  if (container._alpha < 1) {
   container._alpha = 0;
   if (nc > 0) {
    loadContent(nc); // Neuen Inhalt laden,
   } else {
    delete this.onEnterFrame; // oder anhalten, wenn kein Inhalt
   }
  }
 }
}

Diese Funktion blendet zunächst den aktuellen Inhalt mittels einer onEnterFrame-Methode aus und ruft dann die Funktion loadContent auf [ loadContent(nc) ], die den neuen Clip lädt (diese Funktion wird auch in der ersten Funktion "setContent" aufgerufen, wenn noch kein Inhalt angezeigt wird). Der übergebene Wert "nc" ist die Nummmer des neuen Inhaltes.

function loadContent(nc) {
 var stime = getTimer(); // Zeitstempel merken
 loader.loadContent(container, getContentName(nc)); // Inhalt laden lassen
 this.onEnterFrame = function() {
  container._alpha = 0 // unsichtbar halten
  if (loader.isloaded == true) { // Wenn geladen:
   current_content = nc; // Aktuellen Inhalt setzen
   appearContent(); // Inhalt anzeigen
  }
  if (getTimer() - stime > 8000) { // Timeout beim Laden:
   current_content = 0; // Auf Null setzen
   container._alpha = 0;
   delete this.onEnterFrame;
  }
 }
}

Diese Funktion dient zum Laden des neuen Clips. Sie speichert zunächst die Zeit seit Start des Filmes, um einen TimeOut zu realisieren: Wenn Dateien auf dem Server nicht erreichbar sind, sollte der Preloader natürlich nicht ewig angezeigt werden.

Nun wird die gleichnamige Funktion loadContent des Preloaders aufgerufen, in der der Clip geladen wird. die Funktion "getContentName" gibt den Dateinamen anhand der Nummer des Inhaltes zurück.

In einer onEnterFrame-Methode wird nun darauf gewartet, dass loader.isloaded auf true gesetzt wird (wir erinnern uns: Clip vollständig geladen) oder die voreingestellte Zeit (hier: 8000 Milisekunden) überschritten wird. Im ersten Fall wird die Funktion appearContent aufgerufen, die den Inhalt einblendet. Im letzeren Fall wird der aktuelle Inhalt auf Null gesetzt und angehalten.

function appearContent() {
 this.onEnterFrame = function() {
  container._alpha += (100 - container._alpha) / 5; // Inhalt einblenden
  if (container._alpha > 99) {
   container._alpha = 100;
   delete this.onEnterFrame; // Anhalten
  }
 }
}

Diese Funktion blendet den Container nach dem Laden wieder ein. Zuletzt benötigen wir die (schon erwähnte) Funktion, die uns anhand der Nummer einen gültigen Dateinamen liefert. Das lösen wir einfach mit einer switch-Anweisung:

function getContentName(nr) {
 switch(nr) {
  case 1: return "bla.swf"; break;
  case 2: return "censored.swf"; break;
  case 3: return "lol.swf"; break;
  case 4: return "RTFM.swf"; break;
  case 5: return "foo.swf"; break;
 }
 return "nofile.swf";
}

Wenn die Nummer (aus welchen Gründen auch immmer) nicht in unserer Liste steht, geben wir einen Standart-Dateinamen zurück (nofile.swf). Dort könnten wir z.B. eine Meldung ausgeben ("Benutzerfehler").

Autor: Datic
Website: Ekto.net ()


Copyright (c) 2002-2005 by Andreas Schroth

URL: www.computer-tipps.net/webdesign181.html