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:
anschließend besorgen wir uns die nicht ausgeführten <script>-Nodes:
// node ist die Referenz auf die zu befüllende Node und in txt ist das HTML gepseichert
node.innerHTML = txt;
Code:
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):
var sc = node.getElementsByTagName("script");
Code:
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.// 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
Nun müssen wir nur noch die beiden Nodes austauschen und fertig:
Code:
sc[i].parentNode.replaceChild(newSc, sc[i]);
Zu guter Letzt noch den kompletten Code:
Code:
// 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!