Zum Inhalt springen

Eine mögl. Lösung für Reloads für Navigation bei Frames

Erstellt am 2. September 2003 · Noch keine Antworten

Tags: Frage

gaucho ·

Hallo Freunde,

diesmal habe ich keine Frage, sondern eher eine kleine Lösung für ein Problem das mich schon etwas länger beschäftigt.

Ich benutze Frames und hatte bisher das Problem daß ich die Frames nicht korrekt neu laden konnte wenn ich eine neue Seite aus dem Menü aufgerufen habe und diese weitere Unterseiten besaß.
Die Standardlösungen die hierfür angeboten wurden haben mir nicht gefallen.
Standardlösung 1: JavaScript
Mag ich nicht weil oft deaktiviert, ich selbst in der Regel auch)
Standardlösung 2: Lade kompletten Frameset neu (In diesem Fall bräuchte ich nicht mit Frames arbeiten)

Meine Lösung:

Zunächst sei bemerkt, daß diese Lösung nur mit verschachtelten Frames funktioniert.
Den sichtbaren Aufbau den ich verwende ist:
ein Top-Frame,
ein Menu-Frame Links (unterhalb des Top-Frames)
ein Content-Frame (unterhalb Top-Frame, rechts neben dem Menu-Frame)

Nun müssen zunächst die Framesets definiert werden, wie gesagt, verschachtelt.
Das erste Frameset bezieht sich auf die ganze Seite, wie üblich, ist in ROWS aufgeteilt mit dem Top-Frame und einem zusätzlichen "nicht sichtbaren" Frame der den zweiten Frameset beinhaltet.
Das zweite Frameset ist in COLS aufgeteilt und beinhaltet den Menu-Frame und den Content-Frame.

Im Setup-Feld des Templates sieht es dann folgendermaßen aus:

config.intTarget = {$PAGE_TARGET} #Wichtig zum Neuladen von Frames

main_frameset.typeNum = 0 #Haupt-Frameset
top_frame.typeNum = 1 # Top-Frame
sub_frameset.typeNum = 2 # 2. Frameset im Haupt-Frameset verschachtelt
menu_frame.typeNum = 3 #Menu-Frame
content_frame.typeNum = 4 #Content-Frame (Inhalt)



main_frameset.meta < styles.content.meta
main_frameset.frameSet.rows = 84,*
main_frameset.frameSet.params = frameborder="0" border="0" framespacing="0" marginheight="0" marginwidth="0"
main_frameset.frameSet {
1 = FRAME
1.obj = top_frame
1.params = framespacing="0" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"
2 = FRAME
2.obj = sub_frameset
2.params = framespacing="0" frameborder="0" marginwidth="0" marginheight="0"
scrolling="AUTO"
}

sub_frameset.meta < styles.content.meta
sub_frameset.frameSet.cols = 175,*
sub_frameset.frameSet.params = framespacing="0" bordercolor="#FFFFFF" frameborder="O" border="0"
sub_frameset.frameSet {
1 = FRAME
1.obj = menu_frame
1.params = bgcolor="#FFFFFF" framespacing="0" frameborder="0" noresize marginheight="0" border="0" scrolling="NO"
2 = FRAME
2.obj = content_frame
2.params = bgcolor="#FFFFFF" framespacing="0" frameborder="0" noresize marginheight="0" border="0" scrolling="AUTO"
}

So, der Aufbau ist nun erledigt.

Im Menu-Frame benutze ich nun eine grafische Navigation (GMENU).
Sämtliche Seiten sind vom Typ "Standard" oder Erweitert".

Da ich im Top-Frame die Top-Level Navigation habe, und im Content-Frame eine Breadcrumb-Navigation, ist es egal ob nun das linke Menü aufklappt und zusätzlich die nächste Unterebene der Navigation aufklappt oder lediglich ein Menü der nächsten Unterebene, was bei mir der Fall ist.
Das eigentliche Problem ist die Unterscheidung ob ein Menu-Item (Link) Unterseiten besitzt oder nicht. Wenn es Unterseiten besitzt soll das zweite Frameset neu geladen werden, damit auch das Navigationsmenu aktualisiert wird, wenn es keine Unterseiten besitzt, dann soll lediglich der Inhalt der angeclickten Seite im Content-Frame angezeigt werden.

Das Problem ist, daß das "Target" aller Menüeinträge normalerweise gleich ist, egal ob Unterseiten oder nicht.

Wenn die Navigation aufgebaut wird, muß also eine Fallunterscheidung stattfinden.
Also:
Wenn Unterseiten vorhanden sind lade das verschachtelte Frameset, wodurch der Navigations-Frame UND der Content-Frame neu geladen werden. Im Navigations-Frame wird dann ein Menü aus der nächsten Unterebene (Unterseiten) aufgebaut.
Wenn keine Unterseiten vorhanden sind lade nur die verlinkte Seite im Content-Frame, hierdurch bleibt die Navigation, also das bereits bestehende Menü erhalten.

Die Feststellung ob eine Seite Unterseiten hat oder nicht erfolgt über dem "Item-State" (Zustand) IFSUB im Code des Menüs.
Wer die TSRef gelesen hat, der hat dort gelesen daß durch diese Anweisung die Konfiguration des Menüelements aktiviert wird falls die Seite auf die das Menüelement verweist Unterseiten hat. Wer noch weiter gelesen hat, der hat auch gelesen, daß bis auf NO (also dem Normalzustand der Menüeinträge) sämtliche andere Zustände "aktiviert" werden müssen. Dies geschieht indem man Zustand = 1 setzt, also beispielsweise ACT = 1, oder RO = 1, etc.
Ob nun die Eigenschaften des Menüeintrages vom Normalzustand kopiert werden, über die Anweisung Zustand < .NO oder ob der neu definierte Zustand komplett neu aufgebaut wird ist egal.
Wichtig für den angewandten Unterscheidungsfall ist, daß zusätzlich zum Normalzustand noch der Zustand IFSUB definiert wird.

Jetzt muß nur noch unterschieden werden, was der angeclickte Menüeintrag laden soll. Dies geschieht ja über dem Anhängsel &type=... im Link (...index.php?id=...&type=...). In meinem Fall bedeutet das für ein Menüeintrag mit Unterseiten &type=2, für ein Menüeintrag ohne Unterseiten &type=4.
Normalerweise gilt das definierte Target in der Menüdefinition ( Bsp: menu.1.target=myframe) für das gesamte Menü.
Jetzt kommt der Trick:
man kann diesen Wert in den einzelnen Zuständen überschreiben.
Man fügt dem neu definierten Zustand IFSUB die folgende Anweisung hinzu:

altTarget = sub_frameset (in meinem Fall)

Diese Anweisung führt nun dazu, daß Meinüeinträge die Unterseiten Aufweisen nach dem anclicken sowohl den Navigationsframe als auch den Content-Frame neu laden. Die restlichen Menüeinträge laden lediglich die angewählte Seite im Content-Frame während die Navigation so bleibt wie sie ist.

Und das sieht in meinem Code nun so aus:

  marks.LEFT_MENU = HMENU
  marks.LEFT_MENU.special = directory
  marks.LEFT_MENU.special.value.data = field:uid #Startpunkt des Menüs
  marks.LEFT_MENU.1 = GMENU
  marks.LEFT_MENU.1 {
    target = content_frame #Standard-Target des Menüs
    expAll = 0
    NO {
      backColor = #CCFFFF
      wrap = | <BR>
      XY = [10.w]+20, [10.h]+5
      10 = TEXT
      10.text.field = title
      10.fontFile = fileadmin/fonts/verdana.TTF
      10.fontColor = 0,0,0
      10.fontSize = 10
      10.offset = 10, 12
      10.shadow.offset = 1,-1
      10.niceText = 0
          }
    RO < .NO
    RO = 1
    RO {
      10.fontSize = 9
      10.offset = 12, 12
          }
    IFSUB < .NO
    IFSUB = 1
    IFSUB {
      backColor = #CCFFFF
     altTarget = sub_frameset #Target nur für Einträge die auf Unterseiten verweisen
              }
    
                                }

Jetzt werden den Links die korrekten Targets angehängt.

Ich denke ich brauche nicht zu erwähnen daß ich eine Template-Datei mit Markern für das Menü verwendet habe.

So wie beschrieben kann sowohl auf JavaScript verzichtet werden als auch darauf die komplette Seite neu laden zu müssen.
Ein weiterer schöner Nebeneffkt ist, daß wenn lediglich eine Inhaltsseite geladen werden soll, der Eintrag keine Unterseiten hat, nur der Content-Frame neu geladen werden muß und die Navigation auf dieser Ebene auch so stehen bleibt, was das neu laden auch schneller macht.

Ich habe es noch nicht ausprobiert, aber ich denke daß mit ein bißchen Umbauarbeit und Kreativität auch ein ausklappbares Menü wo sämtliche Einträge mit Unterebenen erscheinen soll auch so oder ähnlich erstellt werden kann. Vielleicht kann ja jemand Anderes so etwas in diesem Thread posten.

Nun, ich hoffe dies hilft dem Einen oder Anderen etwas weiter.
Ansonsten noch viel Spaß beim Codieren.

Beste Grüße

Gaucho