Verhalten / Timing bei Zuwesung auf innerHTML
Skeeve
- javascript
Moin!
Ist das Verhalten bei Zuweisung auf innerHTML definiert? Kann man davon ausgeehen, daß der folgende Befehl erst *nach* der vollständigen Auswertung des HTML Codes erfolgt?
Beispieldatei:
<html>
<head>
<script type="text/javascript">
function mach() {
var target= document.getElementById( 'target' );
target.innerHTML=
"<ol><li>eins</li><li>zwei</li><li>drei</li></ol>";
confirm( document.getElementsByTagName( 'li' ).length );
}
</script>
</head>
<body>
<div id="target"/>
<div>
<form>
<button onclick="mach();return false;">mach</button>
</form>
</div>
</body>
</html>
Bei Klick auf "mach" wird dem "target"-div ein neuer Inhalt zugewiesen. Unmittelbar danach zähle ich die <li> Tags. Meine Tests (FF 1.5.0.2 / Mozilla 1.7.12 / Safari 2.0.4, alle Mac OS X) deuten darauf hin, daß dem wohl so ist, da ich jedesmal "3" als Ergebnis erhielt. Aber ist das sicher? Ist das ein definiertes/vorgeschriebenes Verhalten?
-- Skeeve
Hallo,
»»Aber ist das sicher? Ist das ein definiertes/vorgeschriebenes Verhalten?
Meines Wissens ist das theoretisch nicht sicher:
Es kann im Prinzip sein (wenn du seeeeehr schnell klickst), dass die Funktion aufgerufen wird, noch bevor das div "target" wieder geschlossen wurde. Das Ergebnis wäre ein JavaScript-Fehler, da der Browser das Element "target" noch nicht im Dom-Baum finden kann.
Praktisch kannst Du aber davon ausgehen, dass es keine großen Probleme damit gibt, denn die Zeit, in der das der Fall ist, ist äußerst gering.
Moin!
Es kann im Prinzip sein (wenn du seeeeehr schnell klickst), dass die Funktion aufgerufen wird, noch bevor das div "target" wieder geschlossen wurde. Das Ergebnis wäre ein JavaScript-Fehler, da der Browser das Element "target" noch nicht im Dom-Baum finden kann.
Es geht mir weniger darum, ob "target" gefunden wird. Ich überschreibe den Inhalt von target und frage unmittelbar danach den Inhalt ab. Darum geht es.
-- Skeeve
Hi,
Ist das Verhalten bei Zuweisung auf innerHTML definiert? Kann man davon ausgeehen, daß der folgende Befehl erst *nach* der vollständigen Auswertung des HTML Codes erfolgt?
? Der Funktionsaufruf ist nach dem Target. Das Script ist vor dem Target. Der Browser muß auf die Abarbeitung des Scripts warten (s. auch "defer"). Ergo: Keine Probleme.
Aber:
Gruß, Cybaer
? Der Funktionsaufruf ist nach dem Target. Das Script ist vor dem Target. Der Browser muß auf die Abarbeitung des Scripts warten (s. auch "defer"). Ergo: Keine Probleme.
Der Funktionsaufruf ist im Target:
<div id="target"/>
<div>
<form>
<button onclick="mach();return false;">mach</button>
</form>
</div>
Also IMO doch Problem. Allerdings vermutlich nur theoretisch :)
Hi,
Der Funktionsaufruf ist im Target:
Meine letzte Anmerkung überlesen?
Also IMO doch Problem. Allerdings vermutlich nur theoretisch :)
Kein Problem. Der Script-Aufruf-Button wird halt ggf. einfach gelöscht ... :)
Gruß, Cybaer
Hallo,
Kein Problem. Der Script-Aufruf-Button wird halt ggf. einfach gelöscht ... :)
Nee, was ich meinte:
Angenommen du drückst den Button BEVOR der HTML-Parser ans schliessende </div> von target kommt (welches in dem Beispiel eh nicht existiert, aber nehmen wir mal an, das war nur ein Tip-Fehler).
Soweit ich weiß, wird das HTML-Element erst in den DOM-Baum eingehängt, wenn das Element wieder geschlossen wurde.
Folglich würde ein (document.getElementById("target")) NULL liefern, weil dieses Div im DOM-Baum der JavaScript-Engine noch gar nicht existiert.
-> document.getElementById("target").innerHTML würde folglich einen Javascript Fehler liefern.
Es kann natürlich sein, dass das Element doch schon existiert, wenn das Div geöffnet wird. Ist aber afaik nicht zwingend so
(Beispielsweise glaube ich mich an Fehler zu erinnern, wenn ich innerhalb des Bodys einer Seite ein "document.getElementsByTagName("body")[0]" aufgerufen habe.)
Grüße,
Jörg
Hi,
Es kann natürlich sein, dass das Element doch schon existiert, wenn das Div geöffnet wird. Ist aber afaik nicht zwingend so
Ich kenne zumindest kein (HTML-)Gegenbeispiel, und das ist IMHO auch logisch so (s.u.).
(Beispielsweise glaube ich mich an Fehler zu erinnern, wenn ich innerhalb des Bodys einer Seite ein "document.getElementsByTagName("body")[0]" aufgerufen habe.)
Glaub ich nicht. :)
Wenn das 1. Kind des BODYs ein SCRIPT ist, dann wird ein alert(document.getElementsByTagName("body").length) bereits eine "1" ausgeben (überhaupt muß das Element dann schon da sein, da das Script, zumindest via write(), dann bereits das Element füllen kann).
Du kannst das das mal durchexerzieren und hinter jedes DIV einer Seite als 1. Kind ein Script "hide()" setzen.
Und im HEAD ist dann die Funktion hide() definiert mit
document.getElementsByTagName("div")[document.getElementsByTagName("div").length-1].style.display="none";
Gruß, Cybaer
Moin!
- der IE 4 stellt den DOM-Baum erst nach dem kompletten Laden zur Verfügung - kennt aber ohnehin kein getElementBy... (überhaupt: die sinnvolle Abfrage, ob der Browser das überhaupt verarbeiten kann, fehlt ja nur, weil es ein Testscript ist, nicht wahr?! ;-))
Jein. Hier habe ich es nicht eingebaut, weil es ein Testscript ist. Im echten Fall habe ich es nicht eingebaut, weil die Applikation kein IE unterstützt.
-- Skeeve
Hi,
Jein. Hier habe ich es nicht eingebaut, weil es ein Testscript ist. Im echten Fall habe ich es nicht eingebaut, weil die Applikation kein IE unterstützt.
Generell: Wenn es sich um eine Seite fürs Intranet handelt, die nur spezifische Browser zu Gesicht bekommen: Bitte dies angeben. Gemeinhin gehen wir von einer Webseite für alle Browser aus.
Ansonsten: Es gibt auch Nicht-IEs, die getElementBy... nicht kennen. ;) Aber wenn bereits im Vorfeld auf DOM-Fähigkeit abgefragt wird, ist es natürlich egal ... :-)
BTW: Das FORM ist natürlich auch nicht korrekt (und überflüssig).
Gruß, Cybaer
Moin!
Generell: Wenn es sich um eine Seite fürs Intranet handelt, die nur spezifische Browser zu Gesicht bekommen: Bitte dies angeben.
Okay.
Gemeinhin gehen wir von einer Webseite für alle Browser aus.
Hätte ich auch selbst drauf kommen können.
Ansonsten: Es gibt auch Nicht-IEs, die getElementBy... nicht kennen. ;) Aber wenn bereits im Vorfeld auf DOM-Fähigkeit abgefragt wird, ist es natürlich egal ... :-)
Genau. Bereits die Einstiegsseite testet. Es wird (ofiziell) nur Mozilla supportet.
BTW: Das FORM ist natürlich auch nicht korrekt (und überflüssig).
Ich lerne immer wieder hinzu. Als ich mich noch intensiver mit HTML beschäftigt hatte (im letzten Jahrtausend), gab es <button> noch gar nicht und man mußte immer ein <form> um jedweden button setzen.
-- Skeeve
Hi,
Ich lerne immer wieder hinzu. Als ich mich noch intensiver mit HTML beschäftigt hatte (im letzten Jahrtausend), gab es <button> noch gar nicht und man mußte immer ein <form> um jedweden button setzen.
Those times are gone, my friend. ;-)
Aber auch damals war ACTION ein Pflichtattribut in FORM. ;-)
BTW: SELFHTML hat eine sehr schöne Übersicht, in welchen Elementen ein Element vorkommen darf, und was sie wiederum an Elementen enthalten dürfen.
Gruß, Cybaer
Hallo,
<div id="target"/>
Benutze diese Schreibweise bitte nicht, weder in HTML 4 noch in HTML-kompatiblem XHTML 1. Wenn du ein leeres div notieren willst, schreibe wie gewohnt <div></div>.
Du benutzt anscheinend weder XHTML, noch echtes XHTML als application/xml oder application/xhtml+xml. Das führt dazu, dass der Code <div /> nicht als <div></div> angesehen wird (wie es gemäß XML-Regeln nötig wäre), sondern als einfaches Start-Tag <div>. Der Live DOM Viewer zeigt das. Alle folgenden Elemente sind somit Kindelemente dieses divs. Wenn du innerHTML überschreibst, dann wird dementsprechend auch das Formular samt button gelöscht, weil er im div mit id="target" steht.
Siehe auch </archiv/2006/8/t135895/#m882363>.
Mathias
Moin!
<div id="target"/>
Benutze diese Schreibweise bitte nicht,
Danke für den Hinweis! War mir gar nicht mal aufgefallen, daß ich mir den Button zerschieße!
-- Skeeve
Moin!
Korrigierte Fassung der HTML Datei
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<script type="text/javascript">
function mach() {
var target= document.getElementById( 'target' );
target.innerHTML=
"<ol><li>eins</li><li>zwei</li><li>drei</li></ol>";
confirm( document.getElementsByTagName( 'li' ).length );
}
</script>
<body>
<div id="target">
</div>
<div>
<button onclick="mach()">mach</button>
</div>
</body>
</html>
Um es noch mal deutlich zu machen:
Ins target-div schreibe ich über mach() neuen HTML code. Der wird irgendwann geparst und in den DOM tree des documents gehängt. Danach kann man die li Tags im document finden. Meine Frage ist, ob man davon ausgehen kann, daß unmittelbar nach dem ändern des Inhalts von targets innerHTML auch schon die Daten im Tree auffindbar sind, das confirm also immer "3" liefert.
-- Skeeve
hi,
Meine Frage ist, ob man davon ausgehen kann, daß unmittelbar nach dem ändern des Inhalts von targets innerHTML auch schon die Daten im Tree auffindbar sind, das confirm also immer "3" liefert.
Ich würde sagen, ja.
Javascript arbeitet eine Anweisung nach der anderen ab, und eine Zuweisung an .innerHTML dürfte keine Unterbrechung dieser Kette verursachen.
Und da Collections wie die von getElementsBy{irgendwas} gelieferten "lebendig" sind, liefern sie dir immer den aktuellen Zustand.
Theoretische Einschränkung: Da .innerHTML kein definierter Standard ist, kann es keine 100%ige Verlässlichkeit in diesem Punkt geben.
Aber praktisch betrachtet würde ich behaupten, dass du damit in keinem der bekannten Browser, die .innerHTML unterstützen, Probleme bekommen dürftest.
Wenn dir das "reicht" - dann mach's so.
Wenn nicht - dann verzichte auf .innerHTML, und gehe stattdessen nach Standard (DOM) vor. Wenn es dann ein problem gibt, wäre der jeweilige Browser Schuld.
gruß,
wahsaga
Wenn nicht - dann verzichte auf .innerHTML, und gehe stattdessen nach Standard (DOM) vor. Wenn es dann ein problem gibt, wäre der jeweilige Browser Schuld.
Bauen die Browser grundsätzlich erst den DOM-Baum auf und führen dann JS und CSS aus und rendern erst dann? Oder wie machen die das?
Hi,
Bauen die Browser grundsätzlich erst den DOM-Baum auf und führen dann JS und CSS aus und rendern erst dann? Oder wie machen die das?
Üblicherweise arbeitet der Browser in genau der Reihenfolge, wie es im Quelltext notiert ist - und kann soviel, wie er zum Zeitpunkt des Testens können kann. ;-)
D.h., der DOM-Baum wird Schritt für Schritt erzeugt, und wenn das Element ein Stylesheet ist, wird das Stylesheet verarbeitet und wenn das nächste Element ein Script ist, wird das Script verarbeitet (was dann schon auf die Stylesheets zugreifen kann), etc.
Gruß, Cybaer
Üblicherweise arbeitet der Browser in genau der Reihenfolge, wie es im Quelltext notiert ist - und kann soviel, wie er zum Zeitpunkt des Testens können kann. ;-)
Danke, hat geholfen. ;)
Ich habe gestern noch ca. 90 Minuten recherchiert um antworten zu können. Zum Glück haben wir noch den dicken alten Cybaer:
"Cybaer ist der Grösste! Cybaer ist der Groesste! ..."
BTW - was heisst hier "Üblicherweise" genau?
Hi,
Zum Glück haben wir noch den dicken alten Cybaer:
Ich bin nicht dick! Und (fast) im besten Mannesalter! Schleich dich! ;)
BTW - was heisst hier "Üblicherweise" genau?
Das alles auch ganz anders sein kann. >:-> Aber zu 99% ist es halt wie beschrieben.
Gegenbeispiele:
Gruß, Cybaer