David: eval() richtig verwenden?

Hi ihr,

ich habe vor, 2 Frames gleichzeitig zu ändern.. ja, das hatten wir schon 1000 mal, ich weiss. Meine Frage ist auch nur, daß ich als Target einen String übergeben möchte und es jetzt nicht gebacken kriege, das Frame anzusprechen. Angeblich soll eval() ja einen String ausführen, als wäre es ein JS-Befehl?! In SelfHTML steht recht wenig dazu, deswegen wende ich mich an euch.
Folgende Function klappt nicht:

function twoWins(target1, url1, target2, url2) {
  eval("document."+target1+".location.href = " + url1);
  eval("document."+target2+".location.href = " + url2);
}

Gruss,
  David

  1. Tag David!

    Angeblich soll eval() ja einen String ausführen, als wäre es ein JS-Befehl?!

    Ja, das kann man schon so sagen. More info at http://developer.netscape.com/docs/manuals/js/client/jsref/toplev.htm#1063795.

    function twoWins(target1, url1, target2, url2) {
      eval("document."+target1+".location.href = " + url1);
      eval("document."+target2+".location.href = " + url2);
    }

    Die Benutzung von eval() ist hier voellig korrekt. Aber jetzt ueberleg Dir doch mal, wie man denn auf die location eines anderen Frames zugreift. Etwa mit document.Framename.location.href? Waere mir jedenfalls neu. Ich bin mehr fuer parent.Framename.location.href.

    Calocybe

    1. function twoWins(target1, url1, target2, url2) {
        eval("document."+target1+".location.href = " + url1);
        eval("document."+target2+".location.href = " + url2);
      }

      Die Benutzung von eval() ist hier voellig korrekt. Aber jetzt ueberleg Dir doch mal, wie man denn auf die location eines anderen Frames zugreift. Etwa mit document.Framename.location.href? Waere mir jedenfalls neu. Ich bin mehr fuer parent.Framename.location.href.

      Calocybe

      Hallo David, hallo Roland

      eval() ist an dieser Stelle völlig überflüssig. Stellt den Aufruf doch ganz einfach so dar:

      <!--
        function twoWins(target1, url1, target2, url2)
        {
        parent[target1].location.href = url1;
        parent[target2].location.href = url2;
        }

      //-->

      Ich versuche es mal zu erläutern, warum man darauf verzichten kann. Verbesserungen/Ergänzungen sind mehr als erwünscht.

      location.href ist bereits ein Objekt. Ein Unterobjekt des Objektes window oder in diesem Fall ein Unterobjekt des Objektes Frames.
      parent ist ein reservierter Fenstername zum Ansprechen von Fenster und parent.framesname dann ein untergeordnetes Fenster. Framesname wird erst zum Fensterobjekt in Verbindung mit parent. Deshalb kann der Framename problemlos als String übergeben werden.

      Ich habe mir überlegt, daß dieses ja auch für normale framefreie Fenster gelten müßte, die von einer Seite geöffnet werden. Dies ist auch tatsächlich so. Der gleiche Aufruf (Fenster wurde natürlich vorher geöffnet) jedoch diesmal mit einer Fenstervariablen als Übergabewert, ändert ein geöffnetes Fenster.

      Viele Grüße

      Antje

      1. Hi Antje,

        location.href ist bereits ein Objekt.

        als alter Pendant kann ich das sooo nich so stehen lassen (hallo Olli <wink>)

        href ist kein Objekt, sondern eine Eigenschaft vonTyp String des location-Objektes, welches seineszeichens ebenfalls eine (Objekt-)Eigenschaft von document ist etc. (letzteres nur für David )

        Ansonsten wiedermal hervorzüglich von Dir beantwortet :)

        Viel Spaß
        CirTap

      2. Hi Antje!

        parent[target1].location.href = url1;
          parent[target2].location.href = url2;

        Leider hat sich ein kleiner Fehler eingeschlichen. Oder geht das auch? Ich kenne es jedenfalls als
          parent.frames[target1].location.href = url1;
          parent.frames[target2].location.href = url2;

        eval() ist an dieser Stelle völlig überflüssig.

        Zustimmung! (Der eigentliche Sinn dieses Postings, damit Du nicht auf die Idee kommst, ich widerspreche Dir aus Prinzip ;-))
        eval() sollte man ueberhaupt nur dort verwenden, wo es *notwendig* ist. Na gut, bei JS macht es nicht so den uebelsten Unterschied, aber prinzipiell dauert die Auswertung mit eval() laenger, als wenn dasselbe direkt im Source steht, denn bei eval() muss der String erst geparst werden. Vor allem wird das *jedesmal* getan, wenn das eval() in einer Schleife steht, waehrend "richtiger" Sourcecode nur einmal beim Laden geparst wird.

        Und den ungeuebten Blick kann das eval() evtl. auch ein wenig verwirren.

        x = 42; y = 84;
            str = "z = y - x"; x -= 28;
            str += "-16";
            eval(str); alert(z);    // was steht in z?

        parent ist ein reservierter Fenstername zum Ansprechen von Fenster und parent.framesname dann ein untergeordnetes Fenster. Framesname wird erst zum Fensterobjekt in Verbindung mit parent.

        Wieso? Es *gibt* bereits ein Objekt, das diesen Frame verkoerpert. Mit parent.framesname beziehst Du Dich auf dieses, genauso, wie Du Dich mit x auf eine Variable (hoffentlich) existierende namens x beziehst. An dasselbe Objekt kommst Du aber auch mit parent.frames[1] heran, weil ein window-Objekt (was parent ja ist) ein Array namens frames enthaelt. Und weil in JS Arrays assoziativ sind, d.h. die Elemente ueber einen Namen angesprochen werden koennen (in Perl heisst das dann Hash), funktioniert auch parent.frames["framesname"].

        Nun ist es aber so, dass Objekte in JS auch irgendwie nur assoziative Arrays sind. Und zwar kann man eine Eigenschaft object.property genauso gut ueber object["porperty"] ansprechen. So steht das jedenfalls in http://developer.netscape.com/docs/manuals/js/client/jsguide/obj.htm#1008312 (Zitat: "Properties and arrays in JavaScript are intimately related; in fact, they are different interfaces to the same data structure."), und das funktioniert auch.

        Also: Objekte und assoziative Arrays sind nur zwei verschiedene Interfaces zu derselben JS-internen Datenstruktur! Und was heisst das? Das, worin ich am Anfang dieses Postings noch einen Fehler vermutet hatte, ist voellig korrekt. Denn worauf ich mit parent.framename zugreifen kann, das erreiche ich auch mit parent["framename"]. Wenn ich aber bisher mit parent.frames.["framename"] auf einen Frame zugegriffen habe, dann muss doch laut dieser Regel auch parent.frames.framename funktionieren. Und in der Tat, das tut es!

        Wer das selber ausprobieren will, dem poste ich hier zwecks Arbeitsersparnis die Dateien, mit denen ich das ueberprueft habe.

        index.html >>>>

        <HTML>

        <FRAMESET ROWS="*,100" BORDER=0>
                <FRAME NAME="upperframe" SRC="1.html">
                <FRAME NAME="menuframe"  SRC="menu.html">
            </FRAMESET>

        </HTML>
        <<<<<<<<<<<<<<<<<<<<

        menu.html >>>>

        <HTML>
            <BODY>

        <H1 ALIGN=CENTER>MENU</H1>

        <P ALIGN=CENTER>
                <A HREF="javascript:void(parent.upperframe.location.href = '1.html');">1.html via parent.upperframe</A>
                <A HREF="javascript:void(parent['upperframe'].location.href = '2.html');">2.html via parent["upperframe"]</A>
                <A HREF="javascript:void(parent.frames.upperframe.location.href = '3.html');">3.html via parent.frames.upperframe</A>
                <A HREF="javascript:void(parent.frames['upperframe'].location.href = '4.html');">4.html via parent.frames["upperframe"]</A>
            </P>

        </BODY>
            </HTML>
        <<<<<<<<<<<<<<<<<<<

        1.html >>>>

        <HTML>
            <BODY>
            <P STYLE="font-size:114pt; text-align:center; font-family:Arial;">1</P>
            </BODY>
            </HTML>
        <<<<<<<<<<<<<<<<

        Die Dateien 2.html bis 4.html lasse ich mal weg. Das eine Byte kann sicher jeder selber aendern.
        Bitte die umbrochenen Zeilen im Texteditor wieder zu einer zusammenfuegen. Macht sich evtl. nicht so gut, wenn mitten im HREF-Attribut ein Umbruch ist.
        Das void() in menu.html verhindert, das der Navigator komische Sachen macht. *g* Er schreibt sonst den Dateinamen in das Fenster der menu.html, nachdem er im oberen Frame ganz richtig die location gewechselt hat. Ein darauffolgendes view source auf den Menu frame ist einfach nur... seltsam. Nehme ich jetzt mal als Bug hin.

        Es gibt also ein Objekt/Array (sozusagen ein Objekt-Array-Kontinuum *g*) parent, welches fuer jeden der Frames ein Element enthaelt, {welches auf ein window-Objekt verweist, das einen der HTML-Frames repraesentiert} und welches in dem Array mit dem Namen assoziiert wird, den auch der Frame traegt, den das eben genannte window-Objekt repraesentiert. Weiterhin enthaelt das parent-Array-Objekt-Kontinuum ein Element, welches mit dem Namen "frames" assoziiert ist und seinerseits ein Array-Objekt-Kontinuum ist, dessen saemtliche Elemente ebenfalls auf die oben genannten window-Objekte verweisen, die ja (wie gesagt *g*) die HTML-Frames repraesentieren. Klar, ne? ;-)

        Und wenn das stimmt, dann sollte auch der Zugriff ueber parent["frames"].upperframe funktionieren. Fuegen wir also in die menu.html eine weitere Zeile ein:

        <A HREF="javascript:void(parent['frames'].upperframe.location.href = '5.html');">5.html via parent["frames"].upperframe</A>
        <<<<<<<<
        (Und machen natuerlich eine weitere Datei 5.html)

        Und siehe da, es geht!

        Ich habe mir überlegt, daß dieses ja auch für normale framefreie Fenster gelten müßte, die von einer Seite geöffnet werden. Dies ist auch tatsächlich so. Der gleiche Aufruf (Fenster wurde natürlich vorher geöffnet) jedoch diesmal mit einer Fenstervariablen als Übergabewert, ändert ein geöffnetes Fenster.

        Verstehe ich nicht. Meinst Du sowas?
            wnd = window.open(some_url, some_name, some_options);
            wnd.location.href = some_other_url;
        Falls es das war, muss ich jetzt aber sagen, dass mich das nicht vom Hocker haut. ;-)

        Ich versuche es mal zu erläutern, warum man darauf verzichten kann. Verbesserungen/Ergänzungen sind mehr als erwünscht.

        Ist das ok so mit den Ergaenzungen? Dabei wollte ich doch eigentlich nur das mit der Zustimmung schreiben... *g*

        Bye, Roland

        P.S. Alles getestet mit Netscape 4.08 [en] WinNT.

        P.P.S. Und das ist der Beweis, dass auch die zum tausendsten mal gestellten Fragen durchaus auch mal einen interessanten Thread hervorbringen koennen. :-)

        P.P.P.S. Wieso spielen die jetzt schon im Radio am laufenden Band Lacrimosa? Sind die jetzt echt schon so bekannt? Na ok, das war jetzt off-topic.

        (P.)*4.S. Jetzt reicht so ein Bier schon nicht mal mehr fuer ein ganzes Posting!

        1. Hallo Roland,

          Zustimmung! (Der eigentliche Sinn dieses Postings, damit Du nicht auf die Idee kommst, ich widerspreche Dir aus Prinzip ;-))

          :-), ich habe doch auf deinen Kommentar gewartet :-)

          Und den ungeuebten Blick kann das eval() evtl. auch ein wenig verwirren.

          x = 42; y = 84;
              str = "z = y - x"; x -= 28;
              str += "-16";
              eval(str); alert(z);    // was steht in z?

          z=54 84-(42-28)-16=54 :-)

          Das void() in menu.html verhindert, das der Navigator komische Sachen macht. *g* Er schreibt sonst den Dateinamen in das Fenster der menu.html, nachdem er im oberen Frame ganz richtig die location gewechselt hat. Ein darauffolgendes view source auf den Menu frame ist einfach nur... seltsam. Nehme ich jetzt mal als Bug hin.

          Es liegt daran, daß gleichzeitig der Link ausgeführt wird. Da gleiche Problem existiert bei window.open() hinter href. Siehe dazu auch <../../sfausles/tsfa_tcd.htm#a3>

          Ich habe mir überlegt, daß dieses ja auch für normale framefreie Fenster gelten müßte, die von einer Seite geöffnet werden. Dies ist auch tatsächlich so. Der gleiche Aufruf (Fenster wurde natürlich vorher geöffnet) jedoch diesmal mit einer Fenstervariablen als Übergabewert, ändert ein geöffnetes Fenster.

          Verstehe ich nicht. Meinst Du sowas?
              wnd = window.open(some_url, some_name, some_options);
              wnd.location.href = some_other_url;
          Falls es das war, muss ich jetzt aber sagen, dass mich das nicht vom Hocker haut. ;-)

          Nein, ich habe festgestellt, das man über parent auch beliebige Fenster ansprechen kann, die vom Hauptframe geöffnet werden.

          Hier mal die Dateien dazu, ich habe bequemerweise gleich deine genutzt:

          index.htm:
          <html>
          <head>
          <script language="JavaScript">
          <!--

          abc=window.open("5.html","abc1");

          //-->
          </script>

          </head>

          <frameset cols="20%,40%,40%" >
          <frame src="menu1.html" name="links">
          <frame src="1.html" name="mitte">
          <frame src="2.html" name="rechts">
          </frameset>
          </html>

          menui.html

          <html>
          <head>

          <script language="JavaScript">
          <!--
            if (parent.window.length==0) {abc=window.open("1.html","abc1");
                                         mitte=window.open("2.html","mitte1");
                                         rechts=window.open("3.html","rechts1");   }
            alert(parent.window.length); /*mittlerweile habe ich herausgefunden, daß sogar das geht*/

          function twoWins(target1, url1, target2, url2)
               {
                  parent[target1].location.href = url1;

          parent[target2].location.href = url2;

          parent[target2].focus();

          }
          //-->
          </script>

          <title>Menuedatei 2</title>
          </head>
          <body>
          <p><a href="javascript:twoWins('rechts','4.html','mitte','5.html');">Frames werden geändert</a></p><br>

          <p><a href="javascript:twoWins('rechts','1.html','abc','3.html');">Frame und Fenster "abc" wird geändert</a></p><br>
          <p><a href="javascript:twoWins('rechts','2.html','mitte','1.html');">Frames werden geändert</a></p>
          </body>
          </html>

          Diese Datei spricht jetzt Fenster im Frame oder vom Elternframe geöffnete Fenster bzw. von der Seite neu geöffnete Fenster mit der gleichen Fenstervariablen an.

          Außerhalb des Frames werden vorher die Fenster geöffnet und dann mit dem gleichen Aufruf angesprochen. Es spielt keine Rolle, ob sich die Seite im Frame oder nicht befindet. Parent gilt also für frames und normale Fenster gleichen Namens.
          Daraus habe ich geschlußfolgert, daß es auch eine parent.window.length - Eigenschaft geben muß. Und siehe da, es gibt diese Eigenschaft. Sie gibt im Frame parent.frame.length zurück und außerhalb den Wert 0.

          Ich habe mal diese Seiten auf den Server gestellt, damit man dieses Verhalten sehen kann.

          http://pc-anfaenger.de/pca/test/index.htm
          und http://pc-anfaenger.de/pca/test/menue1.html

          alles in allem ist frames wohl eine überflüssige Bezeichnung.

          Ist das ok so mit den Ergaenzungen? Dabei wollte ich doch eigentlich nur das mit der Zustimmung schreiben... *g*

          Aber sicher doch und die von Cir auch. :-)

          P.S. Alles getestet mit Netscape 4.08 [en] WinNT.

          und ich mit dem IE 5 und dem Navi 4.5

          P.P.S. Und das ist der Beweis, dass auch die zum tausendsten mal gestellten Fragen durchaus auch mal einen interessanten Thread hervorbringen koennen. :-)

          dem stimme ich vollkommen zu :-)

          (P.)*4.S. Jetzt reicht so ein Bier schon nicht mal mehr fuer ein ganzes Posting!

          <g> bei mir würde es für 100 reichen :-), bei Wein wäre die Sache anders.

          Viele Grüße

          Antje

          1. Hallo Roland,

            Ich bin zu dusslig den richtigen Dateinamen anzugeben, ein "e" hat sich da reingemogelt.

            http://pc-anfaenger.de/pca/test/index.htm
            und http://pc-anfaenger.de/pca/test/menu1.html

            jetzt stimmts :-), ist ja eigentlich überflüssig zu sagen, aber beim Aufruf von menu1.html allein, zuerst das Frame und sein Fenster schließen.

            Viele Grüße

            Antje

          2. Hi Antje!

            Leider hatte ich heute etwas Stress auf Arbeit, sodass ich kein bisschen Zeit abzweigen konnte, um ueber Dein Posting vernuenftig nachzudenken. Aber ich schau mir's naechste Woche gleich an (bin WE offline), und wenn mir noch was vernuenftiges drauf einfaellt, mach ich einen Reply-Thread auf.

            z=54 84-(42-28)-16=54 :-)

            Mmh, danke. Ich wusste selber nicht, was rauskommt... ;-)

            Na dann, bis naechste Woche
            Roland