Calocybe: / (DHTML) Layer in Tabellenzellen (oder wo liegt das Problem?)

Hallo Leute!

Diesmal habe ich aber ein echtes Problem.

In der folgenden Tabelle moechte ich ein paar kleine Texte dynamisch reinschreiben:

<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" WIDTH="575">
        <TR><TD COLSPAN="4"> </TD></TR>

<TR>
            <TD WIDTH="145" CLASS="y2kcountdown"><LAYER ID="nsy2k0"></LAYER><SPAN ID="iey2k0"></SPAN></TD>
            <TD WIDTH="140" CLASS="y2kcountdown"><LAYER ID="nsy2k1"></LAYER><SPAN ID="iey2k1"></SPAN></TD>
            <TD WIDTH="145" CLASS="y2kcountdown"><LAYER ID="nsy2k2"></LAYER><SPAN ID="iey2k2"></SPAN></TD>
            <TD WIDTH="145" CLASS="y2kcountdown"><LAYER ID="nsy2k3"></LAYER><SPAN ID="iey2k3"></SPAN></TD>
        </TR>
    </TABLE>

Dazu habe ich aehnlich wie in </selfhtml/tfcaa.htm> einen Layer fuer den Navigator und ein SPAN fuer den IE definiert. In folgenden Codeabschnitt, sieht man, wie ich das machen wollte. Mit BODY Onload wird die Funktion wcc() aufgerufen, die wiederum fuer jede der Tabellenzellen die Funktion wcc2() aufruft. Diese schreibt nun abhaengig vom verwendeten Browser den Inhalt einer einzelnen Zelle neu.

<SCRIPT LANGUAGE="JavaScript"><!--
        var y2kMonths, y2kDays, y2kHours, y2kMinutes;

function wcc2(num, content) {
            if (document.all) {
                eval("document.all.iey2k" + num + ".innerHTML = "" + content + "";");
            } else if (document.layers) {
                eval("document.nsy2k" + num + ".document.open();");
                eval("document.nsy2k" + num + ".document.write("" + content + "");");
                eval("document.nsy2k" + num + ".document.close();");
            }
        }

function wcc() {
            wcc2(0, y2kMonths  + " MONATE");
            wcc2(1, y2kDays    + " TAGE");
            wcc2(2, y2kHours   + " STUNDEN");
            wcc2(3, y2kMinutes + " MINUTEN");
        }
    }
    //--></SCRIPT>

<BODY OnLoad="wcc();">

Soweit, so gut. Mit dem IE funktioniert das auch wunderbar, zumindest in der Version 4. Der Netscape bringt es immerhin auch fertig, die Inhalte neu zu schreiben. NUR: Diese Layer sind dann nicht mehr an der richtigen Position innerhalb der Tabelle (irgendwo mitten auf der Seite), sondern ganz oben ganz links ausgerichtet.

Wer weiss warum? Und was kann man dagegen tun? Ich kann zwar mit TOP und LEFT die Layer absolut positionieren, nur das will ich natuerlich nicht.

Calocybe - ganz schoen ratlos

  1. NUR: Diese Layer sind dann nicht mehr an der richtigen Position innerhalb der Tabelle (irgendwo mitten auf der Seite), sondern ganz oben ganz links ausgerichtet.

    Wer weiss warum? Und was kann man dagegen tun? Ich kann zwar mit TOP und LEFT die Layer absolut positionieren, nur das will ich natuerlich nicht.

    Das ist ein ganz typischer Fehler, wenn dein HTML-Code nicht ganz 100! korrekt ist. DHTML ist da sehr empfindlich. Vieleicht liegts ja auch an dem seltsamen html/dhtml Gemisch. Raten kann ich nur nochmal alles aufs Minimum zu reduzieren und dann ganz vorsichtig die Kleinigket suchen, an der es liegt.

    Warum schreibst Du die Tabellen uebrigens nicht gleich jedes mal ganz neu. Das ist sicher weniger aufwendig - sie ist ja nicht gross. dann brauchst Du auch nur ein <div>, wo Du die Tabelle reinpackts.

    Viele Gruesse, Thomas Hieck

    1. Hi!

      Raten kann ich nur nochmal alles aufs Minimum zu reduzieren und dann ganz vorsichtig die Kleinigket suchen, an der es liegt.

      Naja, hatte ich eigentlich schon gemacht. Ich werd's am besten mal mit einem Validator checken.

      Warum schreibst Du die Tabellen uebrigens nicht gleich jedes mal ganz neu. Das ist sicher weniger aufwendig - sie ist ja nicht gross. dann brauchst Du auch nur ein <div>, wo Du die Tabelle reinpackts.

      Und der Netsi macht das mit? Dadurch wuerde doch auf einmal mehr Platz gebraucht werden, und das mag der doch eigentlich nicht so. Wie spricht man die DIV mit Netscape eigentlich an? Ich hatte es mal mit document.divname.document.open() versucht, weil irgendjemand irgendwann mal gepostet hatte, die DIV waere fuer Netsi auch nur ein Layer, aber das ging nicht.

      Calocybe

      1. Hallo Calocybe!

        Vieleicht hilft dir CSS etwas weiter

        .layer { position:relative; andere:sachen; }

        <layer id="" class="layer>

        »»»». dann brauchst Du auch nur ein <div>, wo Du die Tabelle reinpackts.

        Und der Netsi macht das mit? Dadurch wuerde doch auf einmal mehr Platz gebraucht werden, und das mag der doch eigentlich nicht so. Wie spricht man die DIV mit Netscape eigentlich an? Ich hatte es mal mit document.divname.document.open() versucht, weil irgendjemand irgendwann mal gepostet hatte, die DIV waere fuer Netsi auch nur ein Layer, aber das ging nicht.

        Ja. <div> ist für den NS ein layer.

        <div id="Bereichsname">
        ...
        </div>

        dann kannst Du im Script notieren:

        if(document.layers)
        {
        document.Bereichsname.[Eigenschaft/Methode Layerobjekt]
        }
        if(document.all)
        {
        document.all.Bereichsname.[Eigenschaft/Methode all-Objekt]
        }

        <../../sfarchiv/1999_1/t02594.htm#a12255>

        Grüße
        Thomas

      2. »»  Wie spricht man die DIV mit Netscape eigentlich an? Ich hatte es mal mit document.divname.document.open() versucht, weil irgendjemand irgendwann mal gepostet hatte, die DIV waere fuer Netsi auch nur ein Layer, aber das ging nicht.

        Also zum Schreiben mit Netscape einfach nur.

        document.layers["divID"].document.open();
        document.layers["divID"].document.write("blablabla");
        document.layers["divID"].document.close();

        Alternativ dazu der MSIE

        document.all["divID"].innerHTML = "blablabla";

        Viele Gruesse, Thomas Hieck

      3. fenstername.document.images[x].src="bild.gif";
        das schon probiert ?!

        ja, sorry hab ich vergessen anzugeben, klappt irgendwie trotzdem nicht - aber wie es scheint bin ich doch auf dem richtigen weg..

        danke code2i und lulu

        1. Hallo Calocybe!

          Erstmal zum Ansprechen einer DIV in JavaScript: Ja, fuer den Netscape ist eine DIV schlicht und einfach ein LAYER, nur ist er ziemlich waehlerisch; er nimmt nicht jede DIV, wie ich jetzt festgestellt habe. Voraussetzung ist naemlich erstmal ein vorhandenes STYLE-Attribut, und in diesem muss man ihm dann noch bestimmte Positionierungsvorgaben verpassen.

          »»

          So weit ich weiss, sollte eine »id="etwas"« genuügen. (?)

          »»Richtige Regeln habe ich dabei noch nicht erkannt, aber meistens scheint ihm  position:absolute  oder  position:relative  auszureichen.
          »»

          Es gibt leider keine "richtige" Regel wenn es um NS geht, position:absolute; funktioniert so weit so gut -- und ja, mann sollte immer Angaben zu top/left machen. --(nicht nur beim NS, meine Erfahrung ist, daß man für NS zumindest 'width' immer angeben soll.). Position:relative; ist etwas 'bug-lastig' unter NS.

          »»Verwendet man aber  position:static, weigert sich der Netsi vehement, das Ding anzuerkennen.
          »»

          Du sagst es, die Browser kennen das nicht.

          Wenn ich die DIV absolut positioniere, wird die Tabelle wie gewollt dargestellt. Nur was nuetzt mir das, wenn ich nicht weiss, an welcher Pixel-Position die DIV hingehoert? Denn diese verschiebt sich ja staendig mit unterschiedlichen Schriftarten und -groessen.

          »»

          Wenn deine Tabelle im <div> hineinkommt, ist das egal. Mit »postiton:absolut; top:50px; left:100px;« bestimmts du, daß die linke, obere Ecke deines <div>s 50px von oben und 100px von links, gemessen am Fensterrand beginnt. Hast du keine Breite angegeben, behandeln NS und IE dieses <div> unterschiedlich. Hast du eine Breite definiert, wird der Text am Rand umgebrochen, dabei spielt Schriftart und Größe nur eine Nebenrolle.

          Ich kenne mich mit javascript nicht aus, also zu deinem Code kann ich auch nicht relevantes sagen. Nur wie und wo rufst du die Funktion auf, die alles schreiben soll?
          (ich habe den Code kopiert, aber bei mir tut sich weder im IE noch unter NS etwas, als ob der Code gar nicht existierte. (Mein Fehler?))

          Ich glaube, das haengt wirklich irgendwie damit zusammen, dass die DIVs sich in Tabellenzellen befinden, denn in <../../tfcaa.htm> geht's ja. (Wenn ich die ganze Tabelle auf einmal in eine DIV schreibe, so befindet sich diese trotzdem noch in einer uebergeordneten Tabelle.)

          »»

          Wie meinst du das jetzt?
          <table><div><table><tr><td><div>....</tr></table></div></table> ??

          »»Der Netsi hat ja z.B. auch gehoerige CSS-Probleme mit Tabellen.

          Das ist zwar bitter, aber wahr.

          Grüße
          Thomas

          1. Hallo Thomas

            Erstmal zum Ansprechen einer DIV in JavaScript: Ja, fuer den Netscape ist eine DIV schlicht und einfach ein LAYER, nur ist er ziemlich waehlerisch; er nimmt nicht jede DIV, wie ich jetzt festgestellt habe. Voraussetzung ist naemlich erstmal ein vorhandenes STYLE-Attribut, und in diesem muss man ihm dann noch bestimmte Positionierungsvorgaben verpassen.

            So weit ich weiss, sollte eine »id="etwas"« genuügen. (?)

            Nur um sicher zu gehen, dass wir nicht aneinander vorbeireden: Die DIV gibt's natuerlich in jedem Fall, nur muss sie der Netscape als vollwertigen LAYER anerkennen, bevor man mit JavaScript drauf zugreifen kann. Und das hat er eben nur unter solchen gewissen Umstaenden gemacht. Wie gesagt, das kann bei einer anderen Version/Release als 4.08en schon wieder ganz anders sein.

            Es gibt leider keine "richtige" Regel wenn es um NS geht, position:absolute; funktioniert so weit so gut -- und ja, mann sollte immer Angaben zu top/left machen. --(nicht nur beim NS, meine Erfahrung ist, daß man für NS zumindest 'width' immer angeben soll.). Position:relative; ist etwas 'bug-lastig' unter NS.

            Klar, wenn man  position:absolute  verwendet und Angaben zu top/left weglaesst, setzt er die DIV natuerlich in die linke obere Ecke. Und das ist sogar logisch. Leider brauche ich gerade das position:relative; .

            »»Verwendet man aber  position:static, weigert sich der Netsi vehement, das Ding anzuerkennen.
            Du sagst es, die Browser kennen das nicht.

            Aber in SELFHTML steht doch... na gut. ;-)

            Wenn deine Tabelle im <div> hineinkommt, ist das egal. Mit »postiton:absolut; top:50px; left:100px;« bestimmts du, daß die linke, obere Ecke deines <div>s 50px von oben und 100px von links, gemessen am Fensterrand beginnt. Hast du keine Breite angegeben, behandeln NS und IE dieses <div> unterschiedlich. Hast du eine Breite definiert, wird der Text am Rand umgebrochen, dabei spielt Schriftart und Größe nur eine Nebenrolle.

            Ja, schon klar. Ich meinte das so: Ich habe eine grosse Tabelle mit zwei Spalten, die linke 135 Pixel breit, die rechte 575 Pixel breit. In der rechten Spalte steht erst ein Bild, dann etwas Text, und dann soll die besagte DIV bzw. Tabelle kommen. (Das war jetzt etwas vereinfacht, Du kannst Dir das auf http://www.jahr2000.siemens.de/de/index.asp anschauen, das heisst, wenn Du eine schnelle Verbindung hast. *g*) Da aber der Text je nach Schrift eine unterschiedliche vertikale Ausdehnung haben kann, weiss ich natuerlich nicht, an welcher Pixelposition vom oberen Fensterrand die DIV anfangen muss. Der Abstand von links ist natuerlich klar, naemlich 135 Pixel. (Alle Tabellen haben CELLPADDING und CELLSPACING auf 0.) Die Breite ist auch bekannt, naemlich die der Tabellenspalte, also 575px. Und die Hohe.. naja, die kann ich grosszuegig schaetzen, ist ja nur eine Textzeile.

            Ich kenne mich mit javascript nicht aus, also zu deinem Code kann ich auch nicht relevantes sagen. Nur wie und wo rufst du die Funktion auf, die alles schreiben soll?
            (ich habe den Code kopiert, aber bei mir tut sich weder im IE noch unter NS etwas, als ob der Code gar nicht existierte. (Mein Fehler?))

            *g* Ja, aufrufen musst Du die Funktion noch. Ich habe das mit
            <BODY OnLoad="laber()">  gemacht.  (Bzw. <BODY OnLoad="wcc()"> im Falle der 4 DIVs in extra Tabellenzellen)
            Und vielleicht solltest Du vorher die Variablen noch initialisieren, z.B. mit
                function InitCountdown() {
                    var today = new Date();
                    var now = new Date();
                    var CurDate = now.getDate();
                    var todayInMS = today.getTime();

            today.setYear(2000); today.setMonth(0); today.setDate(1);
                    today.setHours(0); today.setMinutes(0); today.setSeconds(0);

            var days_per_month=new Array(31,28,31,30,31,30,31,31,30,31,30,31);
                    var CurMonth = now.getMonth();
                    var countMonth = 11 - CurMonth;
                    var DateLeft=days_per_month[CurMonth]-CurDate;
                    var y2kInMS = today.getTime();
                    var countExact = (y2kInMS - todayInMS) / (1000 * 3600 * 24);
                    var diff = (y2kInMS - todayInMS);
                    var countDays = Math.floor(countExact);
                    var countHours = Math.floor((countExact - countDays) * 24);
                    var diff2 = (diff -((countDays * 1000 * 3600 * 24) + (countHours * 3600 * 1000)));
                    var countMinutes = Math.floor(diff2 / (1000 * 60));

            y2kMonths = countMonth;
                    y2kDays = DateLeft;
                    y2kHours = countHours;
                    y2kMinutes = countMinutes;
                }

            Wie meinst du das jetzt?
            <table><div><table><tr><td><div>....</tr></table></div></table> ??

            Siehe obige Erklaerung, also
            <table><tr><td>...</td><td>...<DIV><table></table></DIV></td><tr></table>
            Und wenn ich die andere Variante nehme, mit 4 DIVs in TDs
            <table><tr><td>...</td><td>...<table><tr>{<TD><DIV></DIV></TD>}*4</tr></table></td><tr></table>

            »»Der Netsi hat ja z.B. auch gehoerige CSS-Probleme mit Tabellen.
            Das ist zwar bitter, aber wahr.

            Die bittere Wahrheit also *g*

            So long,
            Calocybe

            1. Hallo Calocybe!
                
              »»Du kannst Dir das auf http://www.jahr2000.siemens.de/de/index.asp anschauen, das heisst, wenn Du eine schnelle Verbindung hast. *g*)
              »»

              Darf es auch nur ein Glasfaser-Standleitung sein?

              (Ist die Seite von dir? Oder hast du gesehen, daß Unter NS da auch nix geht? Jedenfalls der quelltext zeugt von vielen Proben ;-) )

              So. Ich war so frei und habe mir das alles ein wenig zurechtgestüzt.
              Der Code hier funktionert bei mit unter NS4.5 und IE.
              <html>
              <head>
              <title>Untitled</title>
              <SCRIPT LANGUAGE="JavaScript">
              <!--
                      var y2kMonths, y2kDays, y2kHours, y2kMinutes;

              function InitCountdown() {
                          var today = new Date();
                          var now = new Date();
                          var CurDate = now.getDate();
                          var todayInMS = today.getTime();

              today.setYear(2000); today.setMonth(0); today.setDate(1);
                          today.setHours(0); today.setMinutes(0); today.setSeconds(0);

              var days_per_month=new Array(31,28,31,30,31,30,31,31,30,31,30,31);
                          var CurMonth = now.getMonth();
                          var countMonth = 11 - CurMonth;
                          var DateLeft=days_per_month[CurMonth]-CurDate;
                          var y2kInMS = today.getTime();
                          var countExact = (y2kInMS - todayInMS) / (1000 * 3600 * 24);
                          var diff = (y2kInMS - todayInMS);
                          var countDays = Math.floor(countExact);
                          var countHours = Math.floor((countExact - countDays) * 24);
                          var diff2 = (diff -((countDays * 1000 * 3600 * 24) + (countHours * 3600 * 1000)));
                          var countMinutes = Math.floor(diff2 / (1000 * 60));

              y2kMonths = countMonth;
                          y2kDays = DateLeft;
                          y2kHours = countHours;
                          y2kMinutes = countMinutes;
                      }

              function write_countdown_cell(width, content) {
                          document.writeln('<TD WIDTH="' + width + '" CLASS="y2kcountdown"><B>' +
                              content + '</B></TD>');
                      }

              function wcc2(num, content) {
                          if (document.all) {
                              eval("document.all.iey2k" + num + ".innerHTML = "" + content + "";");
                          } else if (document.layers) {
                          //    eval("document.nsy2k" + num + ".document.open();");
                          //    eval("document.nsy2k" + num + ".document.write("" + content + "");");
                          //    eval("document.nsy2k" + num + ".document.close();");
                          }
                      }

              function wcc() {
                          wcc2(0, y2kMonths  + " MONATE");
                          wcc2(1, y2kDays    + " TAGE");
                          wcc2(2, y2kHours   + " STUNDEN");
                          wcc2(3, y2kMinutes + " MINUTEN");
                      }

              InitCountdown();
                  //--></SCRIPT>

              <STYLE TYPE="text/css">
              <!--
                      td.y2kcountdown { text-align:right; color:#FF0000; font-weight:bold; font-size:10pt; }
                  //-->
              </STYLE>

              </head>

              <body style="font-family:Arial; font-size:14pt; color:blue;">

              OnLoad="wcc();

              <SCRIPT>

              document.writeln('<TABLE BORDER="1" CELLPADDING="0" CELLSPACING="0" WIDTH="575">');
                  /* document.writeln('    <TR><TD COLSPAN="4"> </TD></TR>');*/
                   document.writeln('    <TR>');

              write_countdown_cell(145, y2kMonths  + " MONATE");
                       write_countdown_cell(140, y2kDays    + " TAGE");
                       write_countdown_cell(145, y2kHours   + " STUNDEN");
                       write_countdown_cell(145, y2kMinutes + " MINUTEN");

              document.writeln('    </TR>');
                   document.writeln('</TABLE>');

              </SCRIPT>
                  
              </body>
              </html>

              Das ganze funktioniert bei mir auch in verschachtelten Tabellen. Den Code mit den vielen Tabellen poste ich dir leiber per E-mail.

              Grüße
              Thomas

              1. Hallo Thomas.

                Darf es auch nur ein Glasfaser-Standleitung sein?

                *g* Hauptsache bunt hat sich die Design-Firma wohl gedacht.

                (Ist die Seite von dir?

                Urspruenglich nicht. Die hat eine Design-Firma gemacht. Ich hab das nur erstmal in eine Form gebracht, die man als HTML bezeichnen kann. Bei dem urspruenglichen Code ist einem ja alles moegliche von den letzten drei Tagen wieder hochgekommen.

                Oder hast du gesehen, daß Unter NS da auch nix geht?

                Haeh? Gerade unter NS geht's doch nicht. Oder was meinst Du? Bei dieser offiziellen Adresse habe ich den NS-Teil natuerlich erstmal deaktiviert.

                Jedenfalls der quelltext zeugt von vielen Proben ;-) )

                Ja, meine Nerven auch!

                »»   <SCRIPT>
                »»
                »»     document.writeln('<TABLE BORDER="1" CELLPADDING="0" CELLSPACING="0" WIDTH="575">');
                »»    /* document.writeln('    <TR><TD COLSPAN="4"> </TD></TR>');*/
                »»     document.writeln('    <TR>');
                »»
                »»         write_countdown_cell(145, y2kMonths  + " MONATE");
                »»         write_countdown_cell(140, y2kDays    + " TAGE");
                »»         write_countdown_cell(145, y2kHours   + " STUNDEN");
                »»         write_countdown_cell(145, y2kMinutes + " MINUTEN");
                »»
                »»     document.writeln('    </TR>');
                »»     document.writeln('</TABLE>');
                »»
                »»</SCRIPT>

                Die "write-in-place"-Methode. Tja, das ist jetzt wieder die urspruengliche Version. Und die ging im Prinzip auch bei beiden Browsern. Bis auf ein kleines, aber entscheidendes Problem:

                Vielleicht hast Du schonmal bemerkt, dass manche Seiten beim Navigator, nachdem sie komplett aufgebaut sind, nochmal kurz verschwinden und erneut geladen werden, dann natuerlich sehr schnell weil aus dem Cache. Ich hab noch nicht rausgekriegt, woran das liegen koennte bzw. ob es da irgendeine Regel gibt, jedenfalls gehoert diese Seite dazu. Und so wird also die Seite aufgebaut und der Countdown hingeschrieben und die Seite verschwindet wieder und die ganz oberste Tabelle mit den beiden Bildern wird gemalt... Und das war's dann. Weiter geht's nicht. Der Rest der Seite bleibt leer. Erst nach einem Reload wird die Seite fertiggemalt.

                Schaut man in den Quelltext (den vom Navigator, in dem die writeln()'s bereits ausgefueht sind), sieht man, dass der Kommentar im SCRIPT-Bereich nicht mehr beendet wird, sodass ab dort alles als Kommentar betrachtet wird. Dadurch wird der TABLE nicht mehr geschlossen und so verweigert Netscape die Darstellung.

                Naja, das klingt alles etwas schraeg. Ich will auch nicht sagen, dass das die richtige Erklaerung ist. Aber es ist halt auffaellig, sodass ich da einen Zusammenhang vermute, der irgendwo in den Tiefen des Netscape'schen Quellcodes liegt.

                Seltsam ist auch, dass dieses Verhalten zwar meistens auftritt, wenn ich diese Seite von dem offiziellen Server abrufe, aber eher selten, wenn ich sie von einem kleinen Testserver abrufe, der in der Naehe meines PC steht und zu dem ich eine schnellere Verbindung habe.

                Naja, sehr raetselhaft. Wie's im Moment aussieht, muss ich mir wohl irgendwas anderes ausdenken.

                So far
                Calocybe

                1. Hallo Calocybe!

                  Darf es auch nur ein Glasfaser-Standleitung sein?

                  War mein *ernst*. Ich habe das. :-þ

                  Vielleicht hast Du schonmal bemerkt, dass manche Seiten beim Navigator, nachdem sie komplett aufgebaut sind, nochmal kurz verschwinden und erneut geladen werden, dann natuerlich sehr schnell weil aus dem Cache.

                  Ja, dieses Phänomen kenne ich. Eventuell kommt es bei Seiten vor die einen expire=0 im Header haben (und die Seite eine einzige Tabelle ist, da NS eine Tabelle erst vollständig einliest und erst dann auf dem Bildschirm bringt.)

                  Seltsam ist auch, dass dieses Verhalten zwar meistens auftritt, wenn ich diese Seite von dem offiziellen Server abrufe, aber eher selten, wenn ich sie von einem kleinen Testserver abrufe, der in der Naehe meines PC steht und zu dem ich eine schnellere Verbindung habe.

                  »»

                  Das ist ach der Grund warum ich das nicht so oft zu sehen bekomme, da wie schon oben gesagt, ich habe einen sehr schnellen Zugang ;-).

                  Naja, sehr raetselhaft. Wie's im Moment aussieht, muss ich mir wohl irgendwas anderes ausdenken.

                  Eventuell die Seite auf mehrere kleinere Tabellen aufteilen.?

                  Grüße
                  Thomas