Kann Mozilla kein innerHTML mehr?
Fabian Transchel
- dhtml
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
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
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
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
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
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
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
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
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
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
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.
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
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.
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