/ Startseite / Web-Applikationen / Blog article: Javascript nachladen und ausführen via DocumentRange

RSS

Javascript nachladen und ausführen via DocumentRange

23.07.2008 | 8 Kommentare | Kategorie Web-Applikationen

Für ein Web-Projekt wollte ich dynamisch per Ajax Web-Seiten-Inhalte nachladen. Dabei stieß ich wiedermal auf das Problem, dass ich die Seitenfragmente einfach in die bestehende Web-Seite nachladen möchte, aber der enthaltene Javascript-Code nicht ausgeführt wurde. Dumm nur, dass das nachgeladene Seiten-Fragment zu 99% aus Javascript bestand. Die Lösung für dieses “schwerwiegende” Problem stellte sich letztendlich nach stundenlanger Suche als sehr trivial heraus.

Die Aufgabe besteht — wie schon geschrieben — darin, ein Seitenfragment dynamisch per Ajax nachzuladen und in den bestehenden Content einzufügen. Dank Yahoo’s User Interface ( YUI ) klappte der Ajax-Aufruf zum Laden des Inhalts auch recht flott. Als Antwort kommt aber einen Text-String (responseText) zurück, statt einem erhofften DOM-Node-Objekt.

Ansich lässt sich dieser reine Text einschließlich HTML-Formatierungen einfach in ein bestehendes HTML-Element einbinden, etwa in ein DIV-Element mit der id=”content”:

document.getElementById('content').innerHTML=responseText;

Diese einfache Zeile überschreibt den Inhalt des DIV-Elements durch den erhaltenen String. Wie gesagt werden Format-Anweisungen wie <strong>, <div> und weitere korrekt angezeigt.

Anders aber sieht es mit Javascript aus. Die Javascript-Engine des Browsers reagiert offensichtlich nur auf ein Node-Objekt vom Typ <script>. Es hilft alles nichts, ohne ein vermeintlich aufwändiges Parsen des HTML-Strings gibt es kein Javascript. Die Lösung aber ist doch trivialer, als von mir gedacht.

Die Antwort lautet DocumentFragment. Dieser Typ wird im W3C DOM Standard beschrieben und wird von Firefox wie auch vom Internet Explorer unterstützt. Nachfolgend ist ein Code-Beispiel aufgeführt, welches die Zeichenkette mit dem HTML-Code in der Variable “text” enthält. Weiterhin gilt, dass mein DIV-Element mit der id “content” als Container für den nachgeladenen Code herhalten soll.

var divElement = document.createElement('div');
divElement.innerHTML = text;
var docFrag = document.createDocumentFragment();
while (divElement.firstChild)
docFrag.appendChild(divElement.firstChild);
document.getElementById("document").appendChild(docFrag);

Dieses einfache Beispiel genügt, um sein nachgeladenes Javascript lauffähig zu machen.

Noch ein Tipp: Dieses Beispiel fügt das Code-Fragment als letztes Kind von “content” ein. Alles was bereits im DIV-Element enthalten ist bleibt auch nachher sichtbar. Will man einen leeren Container verwenden, so lässt sich dieser wie folgt entrümpeln:

while ( document.getElementById("content").firstChild )
document.getElementById("content")
.removeChild(contentNode.firstChild);

Beitrag kommentieren 10191 Betrachtungen, 3 davon heute

Relevante Beiträge

Diskussion folgen (RSS)

8 Kommentare zu “Javascript nachladen und ausführen via DocumentRange”

  1. Helge sagt:

    Vielen Dank für diese Lösung! Habe ein ähnliches Problem und ewig versucht einen Workaround zu bauen.

  2. Philip Preißer sagt:

    im oberen Beispiel waren einige Fehler
    (oder eventuell sollten das nur Stichpunkte sein)
    jedenfalls habe ich daraus mal 2 Funktionen gemacht:
     
    function id_add(id, text){
    var div = document.createElement(“div”);
    div.innerHTML = text;
    var docFrag = document.createDocumentFragment();
    while(div.firstChild)
    docFrag.appendChild(div.firstChild);
    document.getElementById(id).appendChild(docFrag);
    }

    function id_clear(id){
    while(document.getElementById(id).firstChild){
    var contentNode = document.getElementById(id);
    contentNode.removeChild(contentNode.firstChild);
    }
    }

  3. Felix sagt:

    Vielen Dank für das Code-Snippet, genau das hat mein Problem gelöst.
    Ich habe den Code von Philip Preißer genommen, der ursprüngliche enthält wie erwähnt Fehler.

  4. Samuel sagt:

    Funktioniert leider nicht im Internet Explorer 8. Hab auch die Erweiterung von Philip Preißer benutzt. Im Mozilla funktioniert es aber einwandfrei.
    Danke

  5. Olli sagt:

    Super Tip, danach habe ich stundenlang gesucht
    Danke!

  6. Michael Kalo sagt:

    Ein weiterer Ansatz könnte dieser Code sein:

    function setContent()
    {
    if (XMLHTTP.readyState == 4) {
    var Content = document.getElementById(‘contentContainer’);
    Content.innerHTML = “”;
    Content.innerHTML += XMLHTTP.responseText;
    //JavaScript Code, der normalerweise beim Seitenaufbau ausgeführt wird, wird in innerHTML nicht ausgeführt. Lösung:
    executeEmbeddedJavaScript(Content.innerHTML);

    }
    }

    //————————————————————————-

    //Findet alle Javascripte im HTML und führt sie in der gefundenen Reihenfolge von oben nach unten aus.
    function executeEmbeddedJavaScript(html)
    {
    if ((html !=null) && (html.length > 0))
    {
    var RegEx_ScriptBeginn = /]*>/ig;
    var RegEx_ScriptEnde = //ig;

    //Findet die erste Stelle im HTML, die mit “” beginnt = Skriptbeginn
    var Script_Beginn = html.search(RegEx_ScriptBeginn);
    //Findet die erste Stelle im HTML, die mit “” beginnt = Skriptende
    var Script_Ende = html.search(RegEx_ScriptEnde);

    while ((Script_Beginn >= 0) && (Script_Ende > Script_Beginn)) {

    try {
    var JavaScriptCode = html.slice(Script_Beginn, Script_Ende).replace(/]*>/ig, “”);
    //Führe den JS Code aus
    try {window.eval(JavaScriptCode);}catch (ex) {}
    //Extrahiere den bereits abgearbeiteten Codeteil aus dem Ausgangs-HTML
    html = html.slice(Script_Ende + “”.length)
    //Findet die erste Stelle im verbliebenen HTML, die mit “” beginnt = Skriptbeginn
    var Script_Beginn = html.search(RegEx_ScriptBeginn);
    //Findet die erste Stelle im verbliebenen HTML, die mit “” beginnt = Skriptende
    var Script_Ende = html.search(RegEx_ScriptEnde);
    }
    catch (ex) {}
    }
    }
    }

  7. Michael Kalo sagt:

    ok…wichtige Code Parts fehlen, wegen Verhinderung von Script Injection….

  8. Stempel Profi sagt:

    Vielen Dank für den Artikel, da ich vor dem Problem stand, dass ich einige Javascript- und CSS-Files dynamisch nachladen mußte, hab ich das für beide Fälle nach dem obigen Schema gelöst. Zusätzlich habe ich eine Funktion eingebaut, die mehrere Dateien mit einem Aufruf laden kann, egal ob Javascript oder Stylesheet.

    Wer so etwas gebrauchen kann, kann sich mein Script auch gern unter stempelprofi.de/files/js-css-loader.zip herunterladen.

    Andreas

Geben Sie einen Kommentar zum Beitrag ab


Theme von Blog Oh! blog