AJAX und damit das dynamische Nachladen von Seiteninhalten mittels JavaScript erfreut sich wachsender Beliebtheit. Um den neuen Inhalt bequem in einen bestehenden Bereich der Seite einzubinden, wird gerne auf die Eigenschaft innerHTML eines Seitenelements zurückgegriffen. Dies ist soweit unproblematisch, da nahezu alle aktuellen Browser diese Eigenschaft unterstützen.
Doch was passiert wenn der neu einzufügende Inhalt auch JavaScript-Code enthält? Im Normalfall wird er durch den Browser einfach ignoriert!
Ist das wirklich so? Und was kann man tun um den Code zur Ausführung zu bringen?
Wirklich ignoriert wird der JavaScript-Code nicht. Wenn man sich den DOM-Baum der Seite nach dem Einfügen anssieht, so wird man feststellen, dass der Code zwar eingefügt aber eben nicht ausgeführt wurde. Das liegt wohl daran, dass die Zuweisung an innerHTML keine Ausführung von JavaScript vorsieht. Warum das so ist soll an dieser Stelle nicht weiter behandelt werden. Ich möchte viel lieber eine Möglichkeit aufzeigen, wie das „dynamische” JavaScript doch zur Ausführung gebracht werden kann.
Hierbei mache ich mir die Möglichkeit zunutze, den JavaScript-Code über das DOM-Modell des Browsers einzufügen. Auf diesem Weg werden die Anweisungen nämlich tatsächlich auch ausgeführt.
var oHead = (document.getElementsByTagName('head'))[0];
// Anlegen eines neuen <script>-Elements
var newScript = document.createElement("script");
newScript.type = "text/javascript";
newScript.id = scriptID;
// zuweisen des eigentlichen Codes an das neue <script>-Element
newScript.text = "alert('Hello world!')";
// Einbinden des neuen <script>-Elements in den <head> der Seite
oHead.appendChild(newScript);
Ausgangslage war nun aber ein Gemisch aus HTML - das ja auch weiterhin über innerHTML eingefügt werden soll - und Javascript-Code. Wie bekommt man nun das Eine dahin und das Andere dorthin?
Wenn man mal davon ausgeht, dass sich maximal ein <script>-Tag in diesem Gemisch befindet, dann kommt man hier mit den Möglichkeiten des RegExp-Objektes schon ein Stück weiter.
// per RegEx wird aus dem "dynamischen" HTML der Script-Code extrahiert
var reScript = /<script[^>]*>(.*)<\/script>/i;
var js = reScript.exec(dynHTML);
// das "dynamische" HTML wird um den Script-Code bereinigt
var html = dynHTML.replace(reScript, '');
Damit wird aus dynHTML ein evtl. vorhandener JavaScript-Code extrahiert. In js[1] haben wir anschließend den „reinen” Code zur Verfügung, während in html keiner mehr enthalten ist.
Der Rest ist nun nur noch Fleißarbeit, html wird mittels innerHTML verarbeitet, während js[1] über das DOM-Modell als <script> eingebunden wird.
function innerHTML_js(pContainer, pDynHTML)
{
// im <head> der Seite nach einem Script-Tag "eindeutig" suchen
var oHead = (document.getElementsByTagName('head'))[0];
var scriptID = 'eindeutig';
// und dieses ggfs. entfernen
// Damit wird verhindert, dass bei jedem Funktionsaufruf
// ein neues Script-Tag angelegt wird.
if (document.getElementById(scriptID))
oHead.removeChild(document.getElementById(scriptID));
// per RegEx wird aus dem "dynamischen" HTML der Script-Code extrahiert
var reScript = /<script[^>]*>(.*)<\/script>/i;
var js = reScript.exec(pDynHTML);
// das "dynamische" HTML wird um den Script-Code bereinigt
var html = pDynHTML.replace(reScript, '');
// und ganz normal über innerHTML eingefügt
var cont = document.getElementById(pContainer);
cont.innerHTML = html;
// wurde im "dynamischen" HTML auch Script-Code gefunden, so wird dieser in
// einem neuen Script-Tag im <head> der Seite eingefügt und ausgeführt!
if (js != null) {
// Anlegen eines neuen <script>-Elements
var newScript = document.createElement("script");
newScript.type = "text/javascript";
newScript.id = scriptID;
// zuweisen des eigentlichen Codes an das neue <script>-Element
newScript.text = js[1];
// Einbinden des neuen <script>-Elements in den <head> der Seite
oHead.appendChild(newScript);
}
}
Beispiel zu innerHTML und JavaScript