Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 <<   zurück
JavaScript und AJAX von Christian Wenz
Das umfassende Handbuch
Buch: JavaScript und AJAX

JavaScript und AJAX
839 S., mit DVD, 39,90 Euro
Galileo Computing
ISBN 3-89842-859-1
gp Kapitel 10 Frames und Iframes
  gp 10.1 Mit Frames arbeiten
    gp 10.1.1 Frames mit HTML
    gp 10.1.2 Frames mit JavaScript füllen
  gp 10.2 Auf Daten von Frames zugreifen
    gp 10.2.1 Auf übergeordnete Frames zugreifen
    gp 10.2.2 Auf Daten von Unterframes zugreifen
    gp 10.2.3 Mehrere Frames gleichzeitig ändern
    gp 10.2.4 JavaScript in Frames auslagern
    gp 10.2.5 Frames zählen
  gp 10.3 Diashow
    gp 10.3.1 Vorbereitungen
    gp 10.3.2 Diashow starten
    gp 10.3.3 Diashow anhalten
    gp 10.3.4 Vorwärts und rückwärts springen
    gp 10.3.5 Diashow verlassen


Galileo Computing

10.2 Auf Daten von Frames zugreifen  downtop

Wie ich bereits erwähnt habe, werden Frames in JavaScript wie Fenster behandelt. Mit den Schlüsselwörtern this und self erhält man also eine Referenz auf den aktuellen Frame – oder eben auf das aktuelle Fenster, wenn die Seite keine Frames enthält.

Auf sich selbst zuzugreifen ist aber nicht sonderlich interessant, und erst recht nichts Neues. Viel eher ist es wichtig, wie man von einer Webseite aus auf die Unterframes zugreifen kann und wie man – von einem Frame aus – auf das in der Hierarchie eine Stufe über einem stehende Element zugreifen kann. Um das anhand eines praktischen Beispiels einmal durchzuführen, wird das Standardbeispiel für diesen Abschnitt leicht verändert.

Das Hauptdokument, es heißt in unserem Beispiel frameset.html, hat folgenden Aufbau:

<html>
<head><title>Frames</title></head>
<frameset cols="150,*">
   <frame name="A" src="a.html" />
   <frame name="B" src="f_b.html" />
</frameset>
<noframes>
<body>Ihr Browser kann mit Frames nichts anfangen!</body>
</noframes>
</html>

Die Datei f_b.html enthält wiederum ein Frameset:

<html>
<head><title>Noch mehr Frames</title></head>
<frameset rows="100,*">
   <frame name="C" src="c.html" />
   <frame name="D" src="d.html" />
</frameset>
</html>

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 10.3     Die Beispielseite im Browser

Abbildung 10.3 veranschaulicht noch einmal den Aufbau: Die Hauptseite enthält zwei Frames – links a.html und rechts f_b.html. Zusätzlich teilt sich f_b.html in die zwei Frames mit dem Inhalt c.html (oben) und d.html (unten) auf.


Galileo Computing

10.2.1 Auf übergeordnete Frames zugreifen  downtop

Wenn Sie in HTML codieren wollen (von »programmieren« kann im Zusammenhang mit HTML ja keine Rede sein), dass sich das Ziel eines Links nicht im aktuellen Frame öffnet, sondern das gesamte Browserfenster für sich beansprucht, machen Sie das für gewöhnlich folgendermaßen:

<a href="seite.htm" target="_top">Hier klicken</a>

Bei JavaScript heißt das Schlüsselwort ganz ähnlich: top. Hiermit erhalten Sie eine Referenz auf das oberste Fenster in der gesamten Frame-Hierarchie. Egal, ob Sie sich in a.html, c.html oder gar in frameset.html befinden – top.location enthält immer "frameset.html" (sowie den Pfad zu dieser Datei).

Oft ist es jedoch von Nutzen, in der Hierarchie nur eine Stufe nach oben zu gelangen, also in unserem Beispiel etwa von c.html eine Referenz auf den Frame mit b.html zu erhalten. Das Schlüsselwort heißt hier parent (dt. »Elternteil«). Wenn Sie sich also in c.html befinden, enthält parent.location den Wert "b.html"; und von b.html aus betrachtet, enthält parent.location den Wert "frameset.html".

Mit parent erhält man bildlich betrachtet immer eine Referenz auf das Dokument, das in dem <frameset>-Tag enthalten ist, das den Frame mit der aufrufenden Datei enthält. Sind in einer Datei also mehrere Framesets ineinander verschachtelt, stehen diese dennoch in der Frame-Hierarchie auf einer Ebene.

Einige Seiten, die ihre Navigation mit Frames erledigen, stellen externe Links in einem ihrer Frames dar, so dass die eigene Navigation immer noch sichtbar bleibt, die fremde Website also in einem Unterframe einer anderen Website dargestellt wird. Das ist zum einen unfreundlich und zum anderen auch schon ein paar Mal erfolgreich von entnervten Sitebetreibern an- bzw. abgemahnt worden. Wenn Sie verhindern wollen, dass Ihre Seiten innerhalb eines fremden Framesets dargestellt werden, haben Sie die folgenden Möglichkeiten, die alle auf demselben Prinzip beruhen: Wenn wir uns nicht im obersten Frame in der Hierarchie befinden, dann machen wir uns zum obersten Frame in der Hierarchie!

<script type="text/javascript"><!--
if (self != top) {
   top.location = self.location;
}
//--></script>

oder:

<script type="text/javascript"><!--
if (self != parent) {
   top.location = self.location;
}
//--></script>

Bauen Sie dieses Skript in all Ihre Webseiten ein, und Sie werden nie wieder von fremden Framesets belästigt werden (wie üblich: sofern JavaScript aktiviert ist)!

Es gibt jedoch auch noch einen anderen Fall: Ein Besucher Ihrer Webseiten setzt ein Lesezeichen (Bookmark) auf eine Seite in einem Frame. Wenn er jedoch das Lesezeichen wieder aufruft, wird lediglich die eine Seite geladen, nicht jedoch die anderen Frames, die beispielsweise die gesamte Navigation enthalten.

Um das Ganze ein wenig anschaulicher zu machen, folgt hier eine Konkretisierung der Aufgabenstellung. Ihre Website besteht aus zwei Frames: Der linke enthält die Navigation, der rechte den Inhalt. Ihre index.html-Datei sieht folgendermaßen aus:

<html>
<head><title>Homepage mit Frames</title></head>
<frameset cols="150,*">
   <frame src="navigation.html" name="Navi" />
   <frame src="inhalt.html" name="Inhalt" />
</frameset>
<noframes>
<body>Ihr Browser kann mit Frames nichts anfangen!
</body>
</noframes>
</html>

In allen Unterseiten sollte nun überprüft werden, ob ein Frameset existiert; wenn nicht, soll das Frameset aufgebaut werden. Dies geschieht mit ein wenig JavaScript: Die URL der aktuellen Seite wird über die Kommandozeile an eine Datei frameset-laden.html übergeben, die die Frame-Struktur erzeugt.

Der folgende Code gehört in alle Unterseiten:

<script type="text/javascript"><!--
if (self == top) {
   location.href = "frameset-laden.html?" + location.href;
}
//--></script>

Die Datei frameset-laden.html wertet die Kommandozeile aus und baut – mittels document.write()die Frame-Struktur auf. Beachten Sie, dass Sie das gesamte Frameset mit JavaScript erzeugen müssen; eine Mischung ist nicht möglich (sie wäre zwar syntaktisch prinzipiell korrekt, die Browser kommen damit aber nicht zurecht).

<html>
<head><title>Homepage mit Frames</title></head>
<script type="text/javascript"><!--
function tag(s) {
   document.write("<" + s + ">");
}
tag('frameset cols="150,*"');
tag('frame src="navigation.html" name="Navi"');
seite = location.search.substring(1,
location.search.length);
   //location.search beginnt mit "?" !
tag("frame src='" + seite + "' name='Inhalt'");
tag("/frameset");
//--></script>
</html>

Denken Sie daran, dass location.search mit einem Fragezeichen beginnt; Sie dürfen daher die Zeichenkette erst ab dem zweiten Zeichen (es hat den Index 1) auswerten.

Die mit JavaScript generierten Framesets lassen sich noch weiter verfeinern. Wenn Sie eine größere Website haben, wird sich im (fiktiven) linken Frame nicht immer dieselbe Navigation befinden. Sie können mehrere Frameset-Dateien erstellen und – je nach aufgerufener Unterseite – einen Link auf eine bestimmte dieser Frameset-Seiten setzen. Stellen Sie sich folgende Zuordnungstabelle vor (Tabelle 8.1):


Tabelle 10.1     URLs und zugehörige Frameset-Dateien

URL-Format Zugehöriges Frameset
/produkte/...
/investorrelations/...
Sonstige

Der Code könnte hier folgendermaßen aussehen:

<script type="text/javascript"><!--
if (self == top) {
   if (location.href.indexOf("/produkte")>=0) {
      location.href = "frameset1.htm?" + location.href;
   } else if (location.href.indexOf("/investorrelations")>=0) {
      location.href = "frameset2.htm?" + location.href;
   } else {
   location.href = "frameset3.htm?" + location.href;
   }
}
//--></script>

Bei einem Schreibzugriff auf location.href wird sofort die neue Seite geladen; JavaScript-Code, der dahinter folgt, wird nicht mehr ausgeführt. Sauberer wäre es natürlich, mit else zu arbeiten.


Galileo Computing

10.2.2 Auf Daten von Unterframes zugreifen  downtop

Referenzen auf die Unterframes eines Fensters werden in dem Array frames (um genau zu sein, unter window.frames oder self.frames oder this.frames) gespeichert. Wenn Sie in der Datei frameset.html auf den linken Frame zugreifen wollen, haben Sie folgende Möglichkeiten:

gp  window.A
gp  window.frames[0]
gp  window.frames["A"]

Aber immer der Reihe nach:

gp  window.A: A ist der Wert des name-Attributs des entsprechenden Frames. Zwei Dinge sollten Ihnen hier deutlich werden: Geben Sie jedem Frame einen einprägsamen Namen, und verwenden Sie keine JavaScript-Begriffe (beispielsweise sollten Sie den Frame nicht "location" nennen, Sie können dann nicht mit window.location auf ihn zugreifen).
gp  window.frames[0]: Wie bereits erwähnt, werden Referenzen auf alle Frames in der jeweiligen HTML-Seite in dem Array frames abgespeichert. Wie bei allen JavaScript-Arrays beginnt der Index bei 0; frames[0] bezeichnet also den ersten Frame. Die Frames werden dabei nach dem Vorkommen im HTML-Dokument nummeriert. Mit frames[1] erhält man somit eine Referenz auf den zweiten Frame in der Beispielseite (b.html).
gp  window.frames["A"]: Das ist eine Mischung aus beiden Varianten. Hier kann man auch auf Frames mit speziellen Namen wie etwa "location" zugreifen. Diese Methode bedeutet jedoch recht viel Tipparbeit, und Sie werden sie sehr selten sehen. Je nachdem, wie einprägsam Ihre Frame-Namen sind, sollten Sie eine der beiden ersten Methoden verwenden.

Abbildung 10.4 verdeutlicht die Zugriffsmöglichkeiten auf andere Frames noch einmal ganz allgemein.

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 10.4     Zugriffsmöglichkeiten auf andere Frames

Mit diesem Wissen können Sie fremden Frames auch noch auf die folgenden Weisen entkommen. Denken Sie daran: Wenn Sie sich im obersten Frame in der Hierarchie befinden, zeigen parent und top auf das aktuelle Fenster:

<script type="text/javascript"><!--
if (top.frames.length>0) {
   top.location = self.location;
}
//--></script>

oder:

<script type="text/javascript"><!--
if (parent.frames.length>0) {
   top.location = self.location;
}
//--></script>

Sie sehen hieran schon, wie man die beiden Methoden – top und parent bzw. frames – miteinander kombinieren kann: Will man auf einen Frame zugreifen, der sich auf derselben Hierarchie-Ebene befindet, so greift man mit top oder (ggfs. mit mehrfacher Anwendung von) parent auf den nächsten gemeinsamen Vorfahren der beiden Frames zu und geht dann über frames in der Hierarchie wieder hinab. Um im Beispiel von oben von dem Frame mit der Datei c.html zu dem Frame mit der Datei d.html zu gelangen, gibt es folgende Möglichkeiten:

gp  parent.D
gp  top.B.frames[1]
gp  parent.parent.B.D

Wenn Sie Zugriff auf den Frame haben, können Sie damit auch auf alle Eigenschaften des Frames oder seiner Unterobjekte zugreifen, beispielsweise auf document, location oder auch auf globale Variablen im JavaScript-Code des Frames.


Galileo Computing

10.2.3 Mehrere Frames gleichzeitig ändern  downtop

Eine der Fragen, die in Newsgroups am häufigsten gestellt werden, lautet: »Wie kann ich den Inhalt mehrerer Frames gleichzeitig ändern?« Dies ist eine Problemstellung, die tatsächlich häufig vorkommt. Denken Sie an eine der Standardanwendungen für Frames: die Navigation. Wenn Sie einen Punkt in der Navigation auswählen, wird (in einem anderen Frame) die entsprechende Inhaltsseite geladen. Jedoch kann es auch vorkommen, dass sich das Aussehen der Navigation selbst ändern soll (beispielsweise soll der gerade ausgewählte Navigationspunkt hervorgehoben werden, damit der Benutzer weiß, wo er sich befindet).

Dieser Effekt ist sehr einfach umzusetzen. Auf die oben aufgezeigte Art und Weise wird auf die entsprechenden Frames zugegriffen und die Eigenschaft location.href entsprechend verändert. Hier lohnt es sich, eine eigene Funktion zu schreiben, die Sie wiederverwenden können. Als Parameter werden Referenzen auf die Frames sowie die zu ladenden URLs übergeben:

<script type="text/javascript"><!--
function ZweiFrames(frame1, url1, frame2, url2) {
   frame1.location.href = url1;
   frame2.location.href = url2;
}
//--></script>

Stellen Sie sich vor, im vorherigen Beispiel befinden Sie sich im Frame A und wollen über einen Link in Frame C die Seite cc.html sowie in Frame D die Seite dd.html laden. Sie können das folgendermaßen tun:

<a href="javascript:ZweiFrames(parent.B.C, 'cc.html', parent.B.D, 'dd.html');">hier klicken</a>

Sie sollten jedoch immer eine Alternative zur Verfügung haben, wenn der Browser des Benutzers kein JavaScript unterstützt. In diesem Fall ist das relativ einfach: Wenn Sie sich die Beispielseite noch einmal anschauen, sehen Sie, dass die Frames C und D in der Datei b.html definiert werden. Sie könnten also alternativ eine Datei bb.html erstellen, die folgendermaßen aussieht:

<html>
<head><title>Noch mehr Frames</title></head>
<frameset rows="100,*">
    <frame name="C" src="cc.html" />
    <frame name="D" src="dd.html" />
  </frameset>
</html>

Der Link vereinfacht sich dann zu folgendem puren HTML:

<a href="bb.html" target="B">hier klicken</a>

Überlegen Sie also immer, ob Sie die Aufgabenstellung auch ohne JavaScript lösen können. Sie vergrößern damit das mögliche Publikum für Ihre Webseite.


Galileo Computing

10.2.4 JavaScript in Frames auslagern  downtop

Wenn Sie eine größere Website mit Frames aufgebaut haben und recht viel JavaScript verwenden, lohnt es sich natürlich, oft benutzte Befehle in Funktionen auszulagern und diese Funktionen auf irgendeine Seite in einem der Frames zu schreiben. Mittels top, parent und frames kann dann auf diese Funktion zugegriffen werden. Ein nahe liegender Ansatz ist es, die Funktionen in der obersten Seite der Hierarchie, also der Seite mit dem Haupt-Frameset abzulegen. Die Funktionen können dann mit top.funktionsname() aufgerufen werden.

Am besten ist es jedoch, wenn alle JavaScript-Funktionen und globalen Variablen in einem Frame abgelegt werden; idealerweise in einem Frame, der sich nie ändert (beispielsweise in einem Navigationsframe). Alternativ dazu können Sie auch auf einen alten HTML-Trick zurückgreifen und einen unsichtbaren Frame verwenden. Der folgende Code erzeugt zwei Frames, wobei der zweite jedoch nicht sichtbar ist, da er nur einen Pixel hoch ist. In diesem Frame lassen sich bequem Funktionen und Variablen ablegen.

<html>
<head><title>Unsichtbarer Frame</title></head>
<frameset rows="*,1" border="0" cellspacing="0" frameborder="0">
  <frame name="sichtbar" src="inhalt.htm" />
  <frame name="unsichtbar" src="skript.htm" />
</frameset>
<noframes>
<body>Ihr Browser kann mit Frames nichts anfangen!
</body>
</noframes>
</html>

Galileo Computing

10.2.5 Frames zählen  toptop

Abschließend noch eine praktische Hilfsfunktion, die erneut den Einsatz von Frames zeigt und auch Programmierung mit Rekursion. Die Funktion subframes(frameref) soll die Anzahl der Unterframes des Frames mit der Referenz frameref ermitteln. Als Unterframes zählen hierbei jedoch nur die Frames, die ein Dokument ohne weiteres Frameset enthalten. Das geht sehr einfach mit Rekursion: Hat ein Frame keine Unterframes, wird er als Dokument gezählt; andernfalls wird die Funktion subframes() rekursiv für alle Unterframes aufgerufen:

function subframes(frameref) {
   if (frameref.frames.length==0) {
      return 1;
   } else {
      var summe = 0;
      for (var i=0; i<frameref.frames.length; i++) {
         summe += subframes(frameref.frames[i]);
      }
      return summe;
   }
}
 <<   zurück
  
  Zum Katalog
Zum Katalog: JavaScript und AJAX
JavaScript und AJAX
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: JavaScript und AJAX - Das Video-Training






 JavaScript und AJAX -
 Das Video-Training


Zum Katalog: Webseiten programmieren und gestalten






 Webseiten
 programmieren
 und gestalten


Zum Katalog: XHTML, HTML und CSS






 XHTML, HTML und CSS


Zum Katalog: CSS-Praxis






 CSS-Praxis


Zum Katalog: AJAX






 AJAX


Zum Katalog: PHP 5 und MySQL 5






 PHP 5 und MySQL 5


Zum Katalog: TYPO3 4.0






 TYPO3 4.0


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de