Hallo,
ich habe ein Script, das wahlweise JSON-Serialisierung benötigt.
Wenn der Browser kein natives JSON unterstützt, dann soll das Script nachgeladen werden, ansonsten am besten nicht - weil es in dem Fall überflüssig ist und gar nicht erst vom Server übertragen und ausgeführt werden muss.
Jetzt finde ich partout keine sinnvolle Möglichkeit, das Script automatisch einzubinden, wenn nötig. Schließlich muss es sofort zur Verfügung stehen - ich kenne aber keine synchrone Möglichkeit, um ein Script nachzuladen (außer synchrones, blockendes XMLHttpRequest - bäh, damit friere ich ja den Browser ein!).
Ausgangslage:
<script src=json.js>
<script src=meinscript.js>
<script>
meinScript.tuWas(); // tuWas braucht JSON
</script>
D.h. JSON einfach immer einbinden, aber das will ich nun vermeiden.
Folgendes ginge und garantiert, dass JSON immer verfügbar ist:
<script>
if (!window.JSON) {
document.write("<script src=json.js></script>);
}
</script>
<script src=meinscript.js>
<script>
meinScript.tuWas(); // tuWas braucht JSON
</script>
Nun will ich aber niemanden raten, in jedes Dokument diesen document.write-Aufruf reinzuschreiben. Nicht weil ich document.write böse finde (den XHTML-Fall halte ich für nicht relevant), sondern weil hier Inline-Script verwendet werden muss.
Bisher habe ich json.js dynamisch beim Initialisieren von meinscript.js geladen. Da wird ein script-Element erzeugt und in den head eingehängt. Das funktioniert wunderbar in 95% der Fälle - aber eben nicht zuverlässig. Manchmal ist das Script noch nicht geladen, window.JSON existiert noch nicht, aber meinScript.tuWas() wird schon ausgeführt.
Okay, also könnte ich das document.write einfach direkt in mein Script schreiben. Funktioniert auch prächtig, allerdings ist JSON nicht in jedem Fall der Scriptverwendung nötig. meinScript.tuWas() braucht nicht notwendig JSON, es soll aber die Möglichkeit geben, das Script so umzuschalten, dass es dann doch JSON braucht. Argh!
Wenn ich in diesem Fall nicht JSON von Anfang an laden will, komme ich doch in die Falle, das Script fallweise nachladen zu müssen. Das ginge ja auch mit document.write:
meinScript = {
tuWas : function () {
if (jsonNötig) {
document.write("<script..>")
}
}
};
var rückgabe = meinScript.tuWas(); // tuWas braucht möglicherweise JSON
Das geht solange, wie ich tuWas während des Ladens der Seite aufrufe - aber üblicherweise arbeitet man ereignisorientiert, also funktioniert document.write nicht mehr und ist sogar schädlich. Ich wüsste auch nicht, wie ich abfragen kann, ob das Dokument schon fertig geladen ist (ohne den load-Handler zu überwachen) und ob ich document.write gebrauchen kann. Selbst wenn, gäbe es keine gute Alternative. createElement("script") funktioniert auch nicht, weil es asynchron läuft. Ich müsste mit einem load-Callbacks arbeiten. Das will ich aber nicht, das wäre sehr kompliziert für den Anwender des Scripts, sondern tuWas soll direkt den Wert zurückgeben, anstatt einen Callback aufzurufen.
Wie würdet ihr das machen?
1. JSON einfach immer mit <script> laden
2. JSON wahlweise mit document.write bei der Initialisierung laden, auch wenn's später nicht verwendet wird
3. JSON wahlweise asynchron mit createElement bei der Initialisierung laden, auch wenn's später nicht verwendet wird
4. JSON laden, wenn es nötig ist (nur wie?)
... noch was anderes / besseres, was mir nicht einfällt
JSON ist jetzt nicht so ein riesiges Script und eigentlich ist es auch in fast allen Anwendungsfällen nötig, insofern ist Möglichkeit 2 erst einmal okay, aber zufrieden bin ich nicht. (Wer XHTML verwendet, muss halt auf die intelligente Einbindung verzichten.)
Mathias