Philipp Sauer: Überschrift in anderem Frame ändern

Hallo liebe Leute!

Ich bin Java-Script Anfänger und habe ein Problem, das ich mit dem Forums-Archiv und der Java-Script-FAQ bislang noch nicht lösen konnte.

Ich habe eine verschachtelte Frame-Seite gebastelt. Das erste Frameset teilt die Seite in die drei Zeilen

  • oben
  • mitte
  • unten

Das nächste Frameset die Zeile 'mitte' noch mal in die Spalten:

  • links
  • hauptframe

Jetzt würde ich gerne die Überschrift im Frame 'oben' anzeigen lassen und den wirklichen Inhalt in 'hauptframe'. Natürlich könnte ich einfach zwei Frames aktualisieren und 30 HTML-Seiten mit den jeweiligen Überschriften basteln, aber das erscheint mir doch etwas umständlich.

Es muss doch gehen bei "onclick" die gewünschte Überschrift als Variable zu übergeben und anzeigen zu lassen.

Das müsste dann doch irgendwie so funzen:

<a href="..." onclick="ueber('LinkXY')>

Ich bin mir gar nicht im klaren, ob ich die Funktion in den Links-Frame, oder, was ich logischer fände, in den oben-Frame schreiben muss.

Außerdem weiß ich nicht, wo ich "document.write" hinschreiben muss, damit es mir nicht die ganze Seite überschreibt.

<script type="text/javascript">
  <!--
     function ueber(capital) {
        document.write(capital);
      }

-->
 </script>

Ich hab das dann auch mit allen möglichen Variationen von top.oben.ueber() und parent.oben.ueber() usw. versucht aufzurufen, leider ohne Erfolg.

Ich gehe mal davon aus, dass dieses Problem hier für viele eine Kleinigkeit ist. Ich hab mir damit aber die halbe Nacht um die Ohren geschlagen, diesen Beitrag auch schon mal vor 8 Std. geschrieben und wieder gelöscht, und würde mich sehr über ein paar helfende Zeilen freuen.

Viele Grüße
Philipp

  1. Jetzt würde ich gerne die Überschrift im Frame 'oben' anzeigen lassen und den wirklichen Inhalt in 'hauptframe'.

    Philipp,
    Du siehst, Frames schaffen nur Probleme. Denk dir am besten eine Lösung für deine Site ohne Frames aus.

    Natürlich könnte ich einfach zwei Frames aktualisieren

    Falls du nicht weißt, wie das geht, frag einfach hier im Forum nach ;-)

    Ich bin mir gar nicht im klaren, ob ich die Funktion in den Links-Frame, oder, was ich logischer fände, in den oben-Frame schreiben muss.

    Weder noch; sondern in den hauptframe.

    Außerdem weiß ich nicht, wo ich "document.write" hinschreiben muss, damit es mir nicht die ganze Seite überschreibt.

    Du willst Fensterinhalte dynamisch ändern, nicht mit document.write(), sondern übers DOM.

    Ich hab das dann auch mit allen möglichen Variationen von top.oben.ueber() und parent.oben.ueber() usw. versucht aufzurufen, leider ohne Erfolg.

    parent dürfte nicht gehen, weil der Elternframe von hauptframe mitte ist, und du so keinen Zugriff auf oben bekommst.

    Ohe es getestet zu haben:
    top.oben.getElementsByTagName("h1")[0].firstChild.nodeValue = "deine neue Überschrift"

    Das Problem dabei ist, dass Nutzer mit deaktiviertem JavaScript weiterhin die alte Überschrift sehen. Womit wir wieder am Anfang wären: Denk dir am besten eine Lösung ohne Frames aus, und ohne JavaScript.
    Gunnar

    --
    Good results come from experience; and experience comes from bad results.
    1. Ohe es getestet zu haben:
      top.oben.getElementsByTagName("h1")[0].firstChild.nodeValue = "deine neue Überschrift"

      danke, werde das später mal probieren.
      Also diese Zeile muss in den Hauptframe, ja?

      Das Problem dabei ist, dass Nutzer mit deaktiviertem JavaScript weiterhin die alte Überschrift sehen. Womit wir wieder am Anfang wären: Denk dir am besten eine Lösung ohne Frames aus, und ohne JavaScript.

      ja, eine alternative lösung ohne java-script werde ich wahrscheinlich noch basteln. Netscape macht auch aus dem Menü einen ziemlichen Mist. ;-)

    2. Hallo Phillip, hallo Gunnar

      Ohe es getestet zu haben:
      top.oben.getElementsByTagName("h1")[0].firstChild.nodeValue = "deine neue Überschrift"

      Dazu muß im oben-Frame schon ein <H1>-Tag (Element) vorhanden sein.
      Außerdem muß da schon Text drinstehen, sonst existiert kein Textknoten auf den zugegriffen werden kann.

      Mit firstChild und lastChild gibts nach meiner Erfahrung oft Probleme, ich halte in so einem Fall childNodes[0] für besser.

      Würde die Funktion auf keinen Fall in den Hauptframe schreiben, da wird ja immer was neues reingeladen.
      Meiner Meinung nach ist die Funktion im Links-Frame am besten aufgehoben.

      Das Problem dabei ist, dass Nutzer mit deaktiviertem JavaScript weiterhin die alte Überschrift sehen. Womit wir wieder am Anfang wären: Denk dir am besten eine Lösung ohne Frames aus, und ohne JavaScript.
      Gunnar

      Warum gibts eigentlich ein Forum für solche Sachen, wenn alle immer schreiben man solls nicht verwenden ?
      (sorry, konnte mir das einfach nicht mehr verkneifen. ich les das laufend hier im forum. daß es ausgerechnet bei deinem beitrag aus mir herausgeplatzt ist, ist reiner zufall)

      gruß
      ptr

      1. hi,

        Das Problem dabei ist, dass Nutzer mit deaktiviertem JavaScript weiterhin die alte Überschrift sehen. Womit wir wieder am Anfang wären: Denk dir am besten eine Lösung ohne Frames aus, und ohne JavaScript.

        Warum gibts eigentlich ein Forum für solche Sachen, wenn alle immer schreiben man solls nicht verwenden ?
        (sorry, konnte mir das einfach nicht mehr verkneifen. ich les das laufend hier im forum. daß es ausgerechnet bei deinem beitrag aus mir herausgeplatzt ist, ist reiner zufall)

        man kann javascript mehr oder weniger sinnvoll einsetzen.

        fuer sinnvoll erachtet es hier m.e. die mehrheit, wenn man dem nutzer mit aktiviertem JS durch dieses einen zusatznutzen bietet, ohne dem benutzer ohne aktiviertes JS wesentliche funktionalitaet der seite vorzuenthalten.

        das zu dem dokument, das ich grade betrachte, auch die richtige, zugehoerige ueberschrift angezeigt wird, koennte man durchaus schon zu den eher wesentlichen "funktionalitaeten" einer webseite zaehlen, deshalb ist hier die "warnung" auch durchaus angebracht.

        gruss,
        wahsaga

  2. Hallo Philipp

    Es muss doch gehen bei "onclick" die gewünschte Überschrift als Variable zu übergeben und anzeigen zu lassen.

    Ja, das geht.

    Das müsste dann doch irgendwie so funzen:

    <a href="..." onclick="ueber('LinkXY')>

    Ja, das funktioniert auch so. Bedingung ist natürlich, daß die angesprochene Funktion "ueber()" das Richtige macht.
    Kleiner Fehler dabei: abschließendes " fehlt. Muß richtig heißen:
    <a href="..." onclick="ueber('LinkXY')">

    Ich bin mir gar nicht im klaren, ob ich die Funktion in den Links-Frame, oder, was ich logischer fände, in den oben-Frame schreiben muss.

    Das geht beides!

    [1]
    Funktion "ueber()" ist im Links-Frame:
    Die Funktion befindet sich im Links-Frame und kann einfach mit:
    <a href="..." onclick="ueber('LinkXY')"> aufgerufen werden.

    [2]
    Funktion "ueber()" ist im oben-Frame:
    Die Funktion befindet sich in einem anderen Frame.
    Du mußt dem "onclick" sagen, welche Funktion aufgerufen werden soll. Dazu mußt du mitteilen, wo diese Funktion zu finden ist, in diesem Fall im oben-Frame (parent.oben bzw. top.oben).
    Das machst du im 1. Beispiel übrigens auch. Dadurch, daß du keine Angabe machst ist festgelegt, daß die Funktion im gleichen Frame(Window) definiert ist.
    Ist die Funktion also im oben-Frame definiert, kannst du Sie vom Links-Frame aus auf folgende Weise aufrufen:
    <a href="..." onclick="parent.oben.ueber('LinkXY')">
    oder:
    <a href="..." onclick="top.oben.ueber('LinkXY')">

    Außerdem weiß ich nicht, wo ich "document.write" hinschreiben muss, damit es mir nicht die ganze Seite überschreibt.

    "document.write()" überschreibt immer die ganze Seite, es wird immer das alte Dokument durch ein neues ersetzt, außer beim Laden.
    Es ist also nur möglich, mit "document.write()" zusätzlichen HTML-Code in ein Dokument zu schreiben, während dieses gerade analysiert wird.

    <script type="text/javascript">
      <!--
         function ueber(capital) {
            document.write(capital);
          }

    -->
    </script>

    Ich hab das dann auch mit allen möglichen Variationen von top.oben.ueber() und parent.oben.ueber() usw. versucht aufzurufen, leider ohne Erfolg.

    Dazu müßte die Funktion im oben-Frame notiert sein und der Aufruf im Links-Frame würde lauten:
    <a href="..." onclick="parent.oben.ueber('LinkXY')"> (siehe [2])
    Beim ersten Aufruf würde die Funktion das Dokument, in der sie steht überschreiben und wäre selbst nicht mehr vorhanden. Gibt beim zweiten Aufruf ne Fehlermeldung, weils die Funktion nicht mehr gibt.

    Für Fall [1] würde das Ganze so aussehen:

    Funktion im Links-Frame:

    <script type="text/javascript">
      <!--
         function ueber(capital) {
         parent.oben.document.write(capital);
         }

    -->
    </script>

    Aufruf der Funktion im gleichen Frame (Links-Frame):

    <a href="..." onclick="ueber('LinkXY')">

    Aber wie gesagt, das taugtin dieser Form nichts für dich, weils die ganze Seite überschreibt und dein schönes Design zerstört.
    Du hättest natürlich die Möglichkeit, mit "document.write()" ein komplettes HTML-Dokument in den oben-Frame zu schreiben.
    Andere Möglichkeit ist, auf im oben-Frame vorhandene Objekte zuzugreifen und deren Inhalt zu ändern.

    Wie weit bist du denn in Javascript, kennst du dich etwas mit DOM aus, weißt du wie man auf Elemente zugreifen kann und was Knoten sind?

    gruß
    ptr

    1. Aber wie gesagt, das taugtin dieser Form nichts für dich, weils die ganze Seite überschreibt und dein schönes Design zerstört.
      Du hättest natürlich die Möglichkeit, mit "document.write()" ein komplettes HTML-Dokument in den oben-Frame zu schreiben.
      Andere Möglichkeit ist, auf im oben-Frame vorhandene Objekte zuzugreifen und deren Inhalt zu ändern.

      Was könnten denn das für Objekte sein? Sehe ich das richtig, dass der eine Lösungsvorschlag das Objekt [H1] anspricht?
      Kann ich auch den Inhalt einer Tabellenzelle ändern?

      Wie weit bist du denn in Javascript, kennst du dich etwas mit DOM aus, weißt du wie man auf Elemente zugreifen kann und was Knoten sind?

      Ich habe mal irgendwann ein Tutorial angefangen, aber leider das meiste vergessen. Sonst nur Scripte angepasst, soweit ich das konnte. Habe schon Lust das mal von Grund auf zu lernen, die Frage ist nur wann. :-)

      Viele Grüße
      Philipp

      1. Hi Philipp

        Was könnten denn das für Objekte sein? Sehe ich das richtig, dass der eine Lösungsvorschlag das Objekt [H1] anspricht?
        Kann ich auch den Inhalt einer Tabellenzelle ändern?

        Ja, das geht. Nach deiner Beschreibung bist du ganz grob mit JS vertraut,
        ich fang hier jetzt mal nicht an, mich mit dir durch den Objektbaum zu hangeln.
        Eine einfache Art, auf ein Objekt zuzugreifen ist über die Methode "getElementById()" des "document-Objektes".

        Dazu mußt du deiner Tabellenzelle eine "id" verpassen:

        <td id="dieZelle">TEXT</td>

        Jetzt kannst du in einer Variablen eine Referenz auf dieses Objekt speichern und weiterverwenden:

        var zelle=document.getElementById('dieZelle');

        wenn dein Skript im Links-Frame notiert ist (was ich empfehle), muß es dort natürlich heißen:

        var zelle=top.oben.document.getElementById('dieZelle');

        oder:
        var zelle=parent.parent.oben.document.getElementById('dieZelle');

        damit hast du dann die Referenz auf die entsprechende Tabellenzelle.

        Wenn in der Zelle schon Text steht enthält sie einen Textknoten.
        Ist nichts anderes in der Zelle notiert, ist der Textknoten der einzige Kindknoten der Zelle und du kannst ihn so ansprechen:

        var text=zelle.childNodes[0];

        Somit ist in der Variablen "text" eine Referenz auf den Textknoten in der Zelle gespeichert. Den Wert des Textknotens kannst du jetzt so ändern:

        text.nodeValue='NEUER TEXT';

        Das geht natürlich auch am Stück:

        parent.parent.oben.document.getElementById('dieZelle').childNodes[0].nodeValue='NEUER TEXT';

        Hab das jetzt mal alles mit "document.getElementById()" gemacht, ist so am einfachsten nachzuvollziehen denke ich.
        Das versteht der NS4.x noch nicht, dazu brauchts schon NS6.x oder höher. Der IE verstehts ab 5.0 .

        Das Ganze ist auch machbar, wenn die Zelle noch keinen Text enthält.
        Dann muß man halt erst einen Textknoten erzeugen. Wenn dirs bis hierher verständlich ist und du interessierst dich auch noch für die Erzeugung eines Textknotens, dann poste ruhig nochmal, auch wenn du irgendwelche Probleme damit hast.

        Nimm dir auch die Anmerkungen der anderen zu Javascript, Frames und den Verzicht darauf zu Herzen.
        Ich denke, die Vorbehalte haben durchaus auch ihre Berechtigung, werden mir halt immer etwas zu undifferenziert und pauschal vorgebracht.
        Diese Techniken haben ja auch ihre Vorteile und wenn diese sinnvoll eingesetzt werden, denke ich schon darüber nach, ob ich diese Vorteile dem Großteil der Benutzer vorenthalten soll, nur damit auch der mit dem IE 3.0 und der mit dem NS 2.0 die Seite genauso sieht wie alle anderen.

        gruß
        ptr

        1. Hallo ptr!

          Danke für Deine ausführliche Anleitung. Es funktioniert sogar! :-)

          Zwischendurch hatte ich noch einen div-container in die Zelle eingebaut, dann gings nicht mehr. Konnte die CSS-Angaben aber genausogut in <td> unterbringen.

          Nur interessehalber wüsste ich gerne wie ich trotz des DIVs den Text hätte ansprechen können. Ich hatte es mit mit childNodes[1] probiert, weil ich einfach mal geraten hatte, dass alle Objekte einfach durchnummeriert werden. Brachte aber nix.

          Also der Tabellenausschnitt war wie folgt:

          <td id="dieZelle">
           <div>
            DER ALTE TEXT
           </div>
          </td>

          Viele Grüße
          Philipp

          1. Hallo Philipp

            Also der Tabellenausschnitt war wie folgt:

            <td id="dieZelle">
            <div>
              DER ALTE TEXT
            </div>
            </td>

            In diesem Fall greifst du mit childNodes[0] auf das div-Element zu, das hier der erste Kindknoten der Tabellenzelle ist.
            Einen zweiten Kindknoten, auf den du mit childNodes[1] zugreifen könntest gibts in dem Fall nicht, da der Text jetzt nicht mehr Kindknoten der Tabellenzelle ist sondern sich im div befindet und daher einen Kindknoten des divs darstellt.
            Hättest so drauf zugreifen können:

            childNodes[0].childNodes[0]

            gruß
            ptr

            1. Hättest so drauf zugreifen können:
              childNodes[0].childNodes[0]

              Ah, verstehe!
              Dankeschön.

  3. Hallo Phillip,

    wie Gunnar richtig schreibt, muß es natürlich "parent.parent.oben" und nicht "parent.oben" heißen.
    Sorry, da hab ich nicht richtig aufgepasst.

    ptr