27.09.2011 16:44:28

innerHTML und das <script>-Tag

Das Problem

Immer wieder stoße ich auf Leute, die Fragen:

Ich lade mit AJAX neuen Inhalt in ein DIV. Das funktioniert wunderbar - aber mein JavaScript im neuen Inhalt wird nicht ausgeführt.
Der Grund ist relativ simpel: neuen Inhalt läd' mal am einfachsten mittels einer Zuweisung an innerHTML in das DIV und dabei werden <script>-Tags einfach nicht ausgeführt. (siehe HTML5 Spezifikation)

Schön und gut - aber wie kann man jetzt das Problem umgehen/lösen?
Das ist nicht besonders aufwändig und ist mit meinem neuen Ansatz auch nicht wirklich problematisch:

Die Lösung

Zuerst müssen wir das innerHTML setzen:
Code:ausführenändern// node ist die Referenz auf die zu befüllende Node und in txt ist das HTML gepseichert node.innerHTML = txt;
anschließend besorgen wir uns die nicht ausgeführten <script>-Nodes:
Code:ausführenändernvar sc = node.getElementsByTagName("script");
die müssen jetzt der Reihe nach völlig kopiert werden - .cloneNode funktioniert da leider nicht, deswegen kopieren wir die Attribute per Hand (sind ja nicht so viele):
Code:ausführenändern// i ist der Laufindex der Schleife var newSc = document.createElement("script"); newSc.type = sc[i].type; newSc.text = sc[i].text; if (sc[i].src) newSc.src = sc[i].src
hierbei ist zu beachten, dass .src nicht einfach kopiert werden darf. Wenn man es trotzdem tut und die <script>-Node eigentlich direkt den Code enthält, wird der Code nicht ausgeführt.

Nun müssen wir nur noch die beiden Nodes austauschen und fertig:
Code:ausführenändernsc[i].parentNode.replaceChild(newSc, sc[i]);

Zu guter Letzt noch den kompletten Code:
Code:ausführenändern// node ist die Referenz auf die zu befüllende Node und in txt ist das HTML gepseichert node.innerHTML = txt; var sc = node.getElementsByTagName("script"); for (var i = 0; i < sc.length; i++){ var newSc = document.createElement("script"); newSc.type = sc[i].type; newSc.text = sc[i].text; if (sc[i].src) newSc.src = sc[i].src sc[i].parentNode.replaceChild(newSc, sc[i]); }

ACHTUNG: externe Skripte werden nicht synchron ausgeführt!