Fabian Transchel: Kann Mozilla kein innerHTML mehr?

Hallo Forum,
bei folgendem kleinen Script (das auf dem Client die _Serverzeit_ anzeigen soll, da die Clientzeit abweichen kann und ich unbedingt die Serverzeit brauche, weil ich weiß, dass die korrekt ist.) scheint der Mozilla die Endlos-Schleife nicht verstehen zu wollen. Beim ersten Aufruf macht er das noch, aber beim zweiten erscheint im <div id="datum"></div> garnichts mehr. Hat jemand eine Idee, wo das Problem ist?

<schnipp>

<div id="datum">
<script type="text/javascript">
var jetzt = new Date();
var lokal = new Date();
<?php
$jetzt = time();
$jetzt *= 1000;
echo ("jetzt.setTime("$jetzt");");
?>
var diff = jetzt.getTime() - lokal.getTime(); // Differenz zwischen Server und Client

function dyndate()
{
var jetzt = new Date();
jetztjetzt = jetzt.getTime();
jetztjetzt+=diff; // Abgleich, sodass der Zeitwert zur Serverzeit wird.
jetzt.setTime(jetztjetzt);
var tag = jetzt.getDate();
var taginwoche = jetzt.getDay();
var wochentag = new Array("Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag");
var stunden = jetzt.getHours();
var minuten = jetzt.getMinutes();
var monat = jetzt.getMonth();
monat++;
var sekunden = jetzt.getSeconds();
if(stunden < 10) stunden = '0' + stunden;
if(minuten < 10) minuten = '0' + minuten;
if(sekunden < 10) sekunden = '0' + sekunden;
document.getElementById("datum").innerHTML = "In Barsinghausen ist es "+stunden+":"+minuten+":"+sekunden+" Uhr am "+wochentag[taginwoche]+", den "+tag+"."+monat+".";
window.setTimeout("dyndate()",300);
}

dyndate();
</script>
<noscript>
<?php
echo("In Barsinghausen ist es ");
echo date("H:i:s");
echo(" Uhr am ");
echo date("d.m");
?>
</noscript></div>

<schnapp>

Moz-Version 1.2.1 -- Sind noch immer DHTML-Fehler drin oder ist das ein Bug? Opera und IE machen das anstandslos.

Fabian

  1. Hallo Fabian,

    dyndate();

    Hier rufst Du während des erstellens der Seite eine Funktion auf, die den DOM-Knoten eines Elements verändern soll, bevor dieses überhaupt vollständig geladen ist. Rufe diese z.B. in <body onLoad> auf oder auch *nach* dem </div>.

    [...] oder ist das ein Bug? Opera und IE machen das anstandslos.

    Ich würde sagen, Opera und IE machen es falsch, beim IE würde es mich nicht wundern, bei Opera wunderts mich dagegen schon...

    Grüße,

    Christian

    --
    Sollen sich alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen und nicht mehr davon erfasst haben als eine Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst.
                          -- Albert Einstein
    1. Hi Christian,

      Hier rufst Du während des erstellens der Seite eine Funktion auf, die den DOM-Knoten eines Elements verändern soll, bevor dieses überhaupt vollständig geladen ist. Rufe diese z.B. in <body onLoad> auf oder auch *nach* dem </div>.

      Ja, geht so. Danke.

      [...] oder ist das ein Bug? Opera und IE machen das anstandslos.

      Ich würde sagen, Opera und IE machen es falsch, beim IE würde es mich nicht wundern, bei Opera wunderts mich dagegen schon...

      Mhh, mit onLoad geht's wie gesagt auch im Mozilla, allerdings flackert es da *grummel* Mal wieder etwas für die Performance-Kategorie >;)

      Grüße zurück, Fabian

      1. Hallo Fabian,

        Mhh, mit onLoad geht's wie gesagt auch im Mozilla, allerdings flackert es da *grummel* Mal wieder etwas für die Performance-Kategorie >;)

        Und wenn Du so wie ich auch vorgeschlagen habe

        ...
        </div>
        <script type="text/javascript">
        <!--
        dyndate();
        //-->
        </script>

        machst? Das geht auch und flackert nicht. (Zumindest bei mir, auch 1.2.1)

        Grüße,

        Christian

        --
        Sollen sich alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen und nicht mehr davon erfasst haben als eine Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst.
                              -- Albert Einstein
        1. Nabend Christian,

          Mhh, mit onLoad geht's wie gesagt auch im Mozilla, allerdings flackert es da *grummel* Mal wieder etwas für die Performance-Kategorie >;)

          Und wenn Du so wie ich auch vorgeschlagen habe

          ...
          </div>
          <script type="text/javascript">
          <!--
          dyndate();
          //-->
          </script>

          machst? Das geht auch und flackert nicht. (Zumindest bei mir, auch 1.2.1)

          Tatsächlich. Wenn du noch 'ne Begründung dafür drauf hast, gebe ich dir beim nächsten Self-Treffen (btw: wann und wo?) einen aus ;-)

          Grüße, Fabian

          1. Hallo Fabian,

            Wenn du noch 'ne Begründung dafür drauf hast,

            Dass es im <div> nicht klappt, ist ja klar, habe ich auch schon im ersten Posting geschrieben. Danach klappt es, weil das Element schon existiert. Wenn Du die Funktion direkt in den Code danach schreibst, dann wird dieser Code praktisch sofort ausgeführt. Wenn Du die Funktion erst mit onLoad ausführst, dann wird der Code erst ausgeführt, wenn das gesamte Dokument geladen ist, und das dauert länger als der direkte Aufruf.

            Grüße,

            Christian

            --
            Sollen sich alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen und nicht mehr davon erfasst haben als eine Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst.
                                  -- Albert Einstein
            1. Hi

              Wenn du noch 'ne Begründung dafür drauf hast,

              Dass es im <div> nicht klappt, ist ja klar, habe ich auch schon im ersten Posting geschrieben. Danach klappt es, weil das Element schon existiert. Wenn Du die Funktion direkt in den Code danach schreibst, dann wird dieser Code praktisch sofort ausgeführt. Wenn Du die Funktion erst mit onLoad ausführst, dann wird der Code erst ausgeführt, wenn das gesamte Dokument geladen ist, und das dauert länger als der direkte Aufruf.

              Nein, damit bin ich nicht ganz zufreiden. Deine These begründet schlüssig die Performancegewinne des _ersten_ Scriptaufrufes, aber auch beim dritten, vierten oder fünfundachzigsten Aufruf ruckelt es bei onLoad="..." noch. onLoad wird ebenfalls _genau einmal_ aufgerufen, also dürfte es daran theoretisch nicht liegen.

              Fabian

              1. Hallo Fabian,

                Nein, damit bin ich nicht ganz zufreiden. Deine These begründet schlüssig die Performancegewinne des _ersten_ Scriptaufrufes, aber auch beim dritten, vierten oder fünfundachzigsten Aufruf ruckelt es bei onLoad="..." noch. onLoad wird ebenfalls _genau einmal_ aufgerufen, also dürfte es daran theoretisch nicht liegen.

                Achso, das hatte ich gar nicht bemerkt.

                File in a bug. (es sollte nicht sein, oder täusche ich mich?)

                Grüße,

                Christian

                --
                Sollen sich alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen und nicht mehr davon erfasst haben als eine Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst.
                                      -- Albert Einstein
              2. Hallo Fabian,

                Nein, damit bin ich nicht ganz zufreiden. Deine These
                begründet schlüssig die Performancegewinne des _ersten_
                Scriptaufrufes, aber auch beim dritten, vierten oder
                fünfundachzigsten Aufruf ruckelt es bei onLoad="..." noch.

                Die Tatsache, dass es bei Inline-JS nicht ruckelt, finde ich
                schon sehr merkwuerdig.

                Ueberigens kannst du noch Performance gewinnen, indem du das
                Ergebnis von document.getElementById() in eine globale
                Variable packst. Ich habe die Erfahrung gemacht, dass ein
                getElementById() mehr Performance als ein Hash-Lookup oder gar
                ein Variablen-Lookup verbraet -- kA, warum.

                Ausserdem reicht es voellig, wenn du das window.setTimeOut auf
                1000 setzt. Date ist eh nicht genauer als sekundengenau.

                Gruesse,
                 CK

                1. Hi CK,

                  Nein, damit bin ich nicht ganz zufreiden. Deine These
                  begründet schlüssig die Performancegewinne des _ersten_
                  Scriptaufrufes, aber auch beim dritten, vierten oder
                  fünfundachzigsten Aufruf ruckelt es bei onLoad="..." noch.

                  Die Tatsache, dass es bei Inline-JS nicht ruckelt, finde ich
                  schon sehr merkwuerdig.

                  Allerdings...

                  Ueberigens kannst du noch Performance gewinnen, indem du das
                  Ergebnis von document.getElementById() in eine globale
                  Variable packst. Ich habe die Erfahrung gemacht, dass ein
                  getElementById() mehr Performance als ein Hash-Lookup oder gar
                  ein Variablen-Lookup verbraet -- kA, warum.

                  Schlechte Engine? Nein, im Ernst: Du hast Recht, das ist überall so. Bei meinem neulich gennanten Planetenscript war es auch nur über globalvariablen möglich, die Intervalle stabil zu halten - bei jeder neuen DOM-Anfrage wird das Ding langsamer und nix dreht sich mehr...

                  Ausserdem reicht es voellig, wenn du das window.setTimeOut auf
                  1000 setzt. Date ist eh nicht genauer als sekundengenau.

                  Nein, das ist nicht richtig. Bei non-realtime-OS (was Windows und auch Linux nunmal nicht sind) sind Ruckler in nicht Pseodo-Kernel-Browsern (also all denen, die nicht IE oder Konqueror heißen) bei allen Rechnern unter 1GHz an der Tagesordnung und da kommt es dann alle Nase lang vor, dass die Uhr um _zwei_ Sekunden springt, denn die Funktion an sich dauert auch länger als NULL Milli-Sekunden. Um das zu beheben nehme ich 300-400 ms, da dann in fast jedem Fall um eine Sekunde verändert wird. Wenn die DOM-Engines schneller wären, so könnte man das natürlich hochschrauben, aber meiner Erfahrung nach geht es nicht.

                  Fabian

                  1. Moin,

                    Um das zu beheben nehme ich 300-400 ms, da dann in fast jedem Fall um eine Sekunde verändert wird. Wenn die DOM-Engines schneller wären, so könnte man das natürlich hochschrauben, aber meiner Erfahrung nach geht es nicht.

                    Bei einer ähnlichen Aufgabe (ok, bei mir waren es Minuten) habe ich einfach die aktuelle Zeit genommen (die musst du ja sowieso haben), die Zeit bis zur nächsten Änderung ausgerechnet und eingetragen. Das passt sich dann automatisch an, falls das System langsamer reagieren sollte.

                    --
                    Henryk Plötz
                    Grüße aus Berlin
                    1. Hi

                      Bei einer ähnlichen Aufgabe (ok, bei mir waren es Minuten) habe ich einfach die aktuelle Zeit genommen (die musst du ja sowieso haben), die Zeit bis zur nächsten Änderung ausgerechnet und eingetragen. Das passt sich dann automatisch an, falls das System langsamer reagieren sollte.

                      Hört sich gut an, geht aber IMHO nicht gut, da ich die Systemverzögerunng in Millisekunden nicht kenne. So kann ich nur mutmaßen, dass die nächste Änderungn in den nächsten 1000ms stattfinden muss, aber eben nicht _wann genau_. Durch die lahmen Interpreter der Browser kann ich eben _nicht_ exakt den Zeitpunkt der Aktualisierung vorraussagen, bei einer Hochsprache sieht das schon ganz anders aus.
                      Da setzt man einen Zeiger auf die Sekundenzähler und gut 'is.
                      Wenn ich das in JS programmieren wollte würde die Funktion länger als eine Sekunde laufen und garnix würde mehr gehen *g*

                      Fabian

                      1. Moin,

                        Hört sich gut an, geht aber IMHO nicht gut, da ich die Systemverzögerunng in Millisekunden nicht kenne. So kann ich nur mutmaßen, dass die nächste Änderungn in den nächsten 1000ms stattfinden muss, aber eben nicht _wann genau_.

                        Doch, window.settimeout("dyndate()", 1000-jetzt.getMilliseconds()); ruft deine Funktion genau nach dem Wechsel auf, bzw. so genau wie möglich. Wenn der Prozessor grade beschäftigt ist, dann geht das natürlich nicht und es wird erst zu nächstbesten Zeitpunkt getan.

                        Durch die lahmen Interpreter der Browser kann ich eben _nicht_ exakt den Zeitpunkt der Aktualisierung vorraussagen

                        Daran änderst du aber mit einem 300ms-Timeout nichts. Im Gegenteil: Es wird dir vergleichsweise häufig passieren dass die Funktion kurz vor dem Wechsel aufgerufen wird, die Uhrzeit noch einmal auf den alten Wert setzt und dann erst wieder in 300ms aktiv werden _kann_ (von dir definiert). Wenn du ihm hingegen sagst, er solle die Funktion doch bitte diemnächst aufrufen und er grade keine Zeit hat, dann ist es egal mit welchem Timeout-Wert du das getan hast: er hat keine Zeit dafür.

                        Wenn ich das in JS programmieren wollte würde die Funktion länger als eine Sekunde laufen und garnix würde mehr gehen *g*

                        Also wenn du eine Funktion hast, die länger als eine Sekunde läuft hast du eh' etwas falsch gemacht.

                        Ich habe grade einen kurzen Test gemacht: Im IE schaltet eine derart per JS gebaute Uhr um, bevor es die Uhr in der Taskleiste[1] tut. Ich habe grade keinen lokal installierten Mozilla parat und der den ich zur Zeit über X über SSH benutze lässt verständlicherweise nicht zum Vergleich heranziehen ;-).

                        [1] Ich kann weit und breit keine andere vorinstallierte Uhr finden und in die Systemsteuerung lässt es mich aus Sicherheitsgründen nicht rein.

                        --
                        Henryk Plötz
                        Grüße aus Berlin
                        1. Hi

                          Hört sich gut an, geht aber IMHO nicht gut, da ich die Systemverzögerunng in Millisekunden nicht kenne. So kann ich nur mutmaßen, dass die nächste Änderungn in den nächsten 1000ms stattfinden muss, aber eben nicht _wann genau_.

                          Doch, window.settimeout("dyndate()", 1000-jetzt.getMilliseconds()); ruft deine Funktion genau nach dem Wechsel auf, bzw. so genau wie möglich. Wenn der Prozessor grade beschäftigt ist, dann geht das natürlich nicht und es wird erst zu nächstbesten Zeitpunkt getan.

                          Exakt das meine ich. Ich kann das natürlich ausrechnen, aber wenn die CPU _am_ Zeitpunkt keine Zeit hat ist das ganze für die Tonne. Halt Windoof, weil da kommt das alle Nase lang vor.

                          Durch die lahmen Interpreter der Browser kann ich eben _nicht_ exakt den Zeitpunkt der Aktualisierung vorraussagen

                          Daran änderst du aber mit einem 300ms-Timeout nichts. Im Gegenteil: Es wird dir vergleichsweise häufig passieren dass die Funktion kurz vor dem Wechsel aufgerufen wird, die Uhrzeit noch einmal auf den alten Wert setzt und dann erst wieder in 300ms aktiv werden _kann_ (von dir definiert). Wenn du ihm hingegen sagst, er solle die Funktion doch bitte diemnächst aufrufen und er grade keine Zeit hat, dann ist es egal mit welchem Timeout-Wert du das getan hast: er hat keine Zeit dafür.

                          Ich bräuchte eine Funktion, die die alte Uhrzeit übergibt, ne? Die Frage ist nicht, wie ich sie übergeben bekomme, sondern ob der übergebene Zeitstempel dann noch stimmt.

                          Fabian