den grundsätzlichen Aufbau kann ich allerdings nicht ändern, d.h. das inline-JS in einen Callback zu packen o.ä. wird nicht funktionieren
Dieser Aufbau ist aber für das Problem verantwortlich.
Wenn du in einem script-Element im <body> jQuery verwenden willst, dann musst du es SYNCHRON davor laden. Mit createElement("script")/appendChild lädst du es jedoch ASYNCHRON. Damit ist natürlich nicht garantiert, dass das externe Script geladen ist, wenn die Scripte im <body> ausgeführt werden.
Wenn du synchron laden willst, verwende ausschließlich document.write. Dann wird das Parsing des Dokuments und damit das Ausführen der Scripte angehalten, bis jQuery geladen und ausgeführt ist.
Du kannst aber m.W. nicht direkt nach document.write() deine Startup-Funktion ausführen. document.write("<script src='...'></script>">) ist nur für darauffolgende Scripte synchron, der Code direkt nach dem document.write-Aufruf hat noch keinen Zugriff auf die Objekte, die im externen Script definiert werden. Bei document.write() ist ein Callback also nicht möglich.
Folgendes ginge m.W. (ungetestet)
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<!-- Hier kann jQuery eingebunden sein oder auch nicht -->
<script>
[code lang=javascript]if (!window.jQuery) {
// Lädt das externe Script und blockt den HTML-Parser
document.write("<script src='jquery.js'><\/script>");
}
</script>
<script>
startup(); // Hier ist garantiert, dass jQuery geladen ist
</script>
</head>
<body>
<h1 id="test">TEST HEADING</h1>
<script type="text/javascript">
$('h1').css('color', 'red'); // Hier ist ebenfalls garantiert, dass jQuery geladen ist
</script>
</body>
</html>[/code]
Allgemein ist das natürlich ein verbesserungsfähiger Aufbau. Üblicherweise läd man JavaScript-Code aus Performancegründen am Ende des Dokuments, dann völlig asynchron mit Callbacks. JavaScript-Code mitten ins Dokument einzubetten, erschwert die ganze Sache und macht asynchrones Laden mit Callback unmöglich. Das nennt sich Unobtrusive JavaScript.
Mathias