Exécution des éléments <script> insérés avec .innerHTML

112

J'ai un script qui insère du contenu dans un élément en utilisant innerHTML.

Le contenu pourrait par exemple être:

<script type="text/javascript">alert('test');</script>
<strong>test</strong>

Le problème est que le code à l'intérieur de la <script>balise n'est pas exécuté. Je l'ai googlé un peu mais il n'y avait pas de solutions apparentes. Si j'ai inséré le contenu à l'aide de jQuery, $(element).append(content);les parties du script ont evalété injectées dans le DOM.

Quelqu'un a-t-il un extrait de code qui exécute tous les <script>éléments? Le code jQuery était un peu complexe, donc je ne pouvais pas vraiment comprendre comment cela était fait.

Modifier :

En jetant un œil dans le code jQuery, j'ai réussi à comprendre comment jQuery le fait, ce qui a abouti au code suivant:

Demo:
<div id="element"></div>

<script type="text/javascript">
  function insertAndExecute(id, text)
  {
    domelement = document.getElementById(id);
    domelement.innerHTML = text;
    var scripts = [];

    ret = domelement.childNodes;
    for ( var i = 0; ret[i]; i++ ) {
      if ( scripts && nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
            scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
        }
    }

    for(script in scripts)
    {
      evalScript(scripts[script]);
    }
  }
  function nodeName( elem, name ) {
    return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
  }
  function evalScript( elem ) {
    data = ( elem.text || elem.textContent || elem.innerHTML || "" );

    var head = document.getElementsByTagName("head")[0] || document.documentElement,
    script = document.createElement("script");
    script.type = "text/javascript";
    script.appendChild( document.createTextNode( data ) );
    head.insertBefore( script, head.firstChild );
    head.removeChild( script );

    if ( elem.parentNode ) {
        elem.parentNode.removeChild( elem );
    }
  }

  insertAndExecute("element", "<scri"+"pt type='text/javascript'>document.write('This text should appear as well.')</scr"+"ipt><strong>this text should also be inserted.</strong>");
</script>
Phidah
la source
1
Pourquoi ne pouvez-vous pas simplement itérer les enfants de l'élément, et pour chacun d'entre eux qui est un élément de script, vous évaluez simplement () le innerHtml de cet enfant? C'est ainsi que je l'ai vu faire par un grand fournisseur de composants, chaque fois qu'ils effectuent un rappel ajax qui ajoute des éléments au DOM, ils font exactement cela. Gardez à l'esprit que cela peut être lent, en particulier dans IE7.
slugster
2
Andreas: Si j'ajoute une fonction, par exemple function testFunction(){ alert('test'); }au code inséré dans innerHTML, et que j'essaye de l'appeler, cela indique que la fonction n'est pas définie.
phidah
1
Phidah génial, fonctionne comme le charme, bravo
Marcin
3
Je pense qu'il est absolument important de comprendre qu'il s'agit d'un comportement prévu par le navigateur pour empêcher les attaques de script intersite. Si le texte que vous définissez comme innerHTML est fourni par Bob, il s'exécuterait sur le navigateur d'Alice causant des dommages (pensez à un forum où les gens peuvent écrire des commentaires en y ajoutant des balises de script). Vous pouvez en savoir plus ici: en.wikipedia.org/wiki/Cross-site_scripting . Restez économisez!
Xatian
1
Un HTML a beaucoup changé depuis 2010. Ces jours-ci, vous voulez peut-être regarder: stackoverflow.com/a/58862506/890357
marciowb

Réponses:

27

Le script de l'OP ne fonctionne pas dans IE 7. Avec l'aide de SO, voici un script qui fait:

exec_body_scripts: function(body_el) {
  // Finds and executes scripts in a newly added element's body.
  // Needed since innerHTML does not run scripts.
  //
  // Argument body_el is an element in the dom.

  function nodeName(elem, name) {
    return elem.nodeName && elem.nodeName.toUpperCase() ===
              name.toUpperCase();
  };

  function evalScript(elem) {
    var data = (elem.text || elem.textContent || elem.innerHTML || "" ),
        head = document.getElementsByTagName("head")[0] ||
                  document.documentElement,
        script = document.createElement("script");

    script.type = "text/javascript";
    try {
      // doesn't work on ie...
      script.appendChild(document.createTextNode(data));      
    } catch(e) {
      // IE has funky script nodes
      script.text = data;
    }

    head.insertBefore(script, head.firstChild);
    head.removeChild(script);
  };

  // main section of function
  var scripts = [],
      script,
      children_nodes = body_el.childNodes,
      child,
      i;

  for (i = 0; children_nodes[i]; i++) {
    child = children_nodes[i];
    if (nodeName(child, "script" ) &&
      (!child.type || child.type.toLowerCase() === "text/javascript")) {
          scripts.push(child);
      }
  }

  for (i = 0; scripts[i]; i++) {
    script = scripts[i];
    if (script.parentNode) {script.parentNode.removeChild(script);}
    evalScript(scripts[i]);
  }
};
Larry K
la source
4
Mieux vaut utiliser jQuery $(parent).html(code)- voir ma réponse ci-dessous.
iirekm
une fois le script injecté dans DOM, comment le supprimer?
S4beR
1
Le script n'est pas récursif, il ne regardera donc que les enfants directs. Cela fonctionne pour moi:if (nodeName(child, "script" ) && (!child.type || child.type.toLowerCase() === "text/javascript")) { scripts.push(child); } else { exec_body_scripts(child); }
st4wik
2
Notez que le code ci-dessus n'exécute pas les scripts qui se chargent via src. Le script ci-dessus peut être modifié pour vérifier elem.srcet définir de manière conditionnelle la srcpropriété de l'élément de script créé au lieu de définir son contenu textuel.
Ryan Morlok
Pourquoi ne pas utiliser l' evalastuce globale au lieu de créer un <script>élément et de l'insérer dans le <head>? Ils exécutent tous les deux du code JS sans exposer la fermeture actuelle.
Finesse
31

@phidah ... Voici une solution très intéressante à votre problème: http://24ways.org/2005/have-your-dom-and-script-it-too

Donc, cela ressemblerait à ceci à la place:

<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />

user447963
la source
2
et encore mieux, pas besoin d'avoir une image avec l'événement "onerror", bien pour une injection XSS rapide jvfconsulting.com/blog/47/... :)
baptx
11
Vous pouvez utiliser <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" onload="alert('test');">si vous souhaitez empêcher une requête http inutile.
Savas Vedova
1
aimer ! (ajouté style="display:none;) pour masquer l'icône d'image cassée
kris
En fait, <style>c'est mieux que <img>, car il ne fait pas de demande de réseau
bassin
24

Voici un script plus court et plus efficace qui fonctionne également pour les scripts avec la srcpropriété:

function insertAndExecute(id, text) {
    document.getElementById(id).innerHTML = text;
    var scripts = Array.prototype.slice.call(document.getElementById(id).getElementsByTagName("script"));
    for (var i = 0; i < scripts.length; i++) {
        if (scripts[i].src != "") {
            var tag = document.createElement("script");
            tag.src = scripts[i].src;
            document.getElementsByTagName("head")[0].appendChild(tag);
        }
        else {
            eval(scripts[i].innerHTML);
        }
    }
}

Remarque: bien que cela evalpuisse causer une faille de sécurité s'il n'est pas utilisé correctement, c'est beaucoup plus rapide que de créer une balise de script à la volée.

DiviséByZéro
la source
1
cela m'a aidé mais je me sens sale en utilisant eval. en s'assurant que le texte ne peut pas être compromis, je ne vois pas de vulnérabilité.
John
@ random-user a evalété conçu pour blesser les utilisateurs. Toute exécution de script dynamique est un risque et c'est pourquoi CSP l'appelle 'unsafe-eval'parce que c'est le cas. Vous nuit également à la sécurité de vos sites si vous l'utilisez dans une bibliothèque car ils ne peuvent pas le désactiver.
jonathanKingston
Tester cela dans Chrome 44 provoque une boucle infinie lorsque appendChild est appelé car cela incrémente la valeur scripts.length.
Codewithcheese
4
Les scripts avec la srcpropriété seront téléchargés de manière asynchrone et exécutés comme arrivés. La commande n'est pas conservée. Les scripts en ligne seront également exécutés dans le désordre, de manière synchrone avant les scripts asynchrones.
robert4
21

Vous ne devez pas utiliser la propriété innerHTML mais plutôt la méthode appendChild du Node: un nœud dans une arborescence de documents [HTML DOM]. De cette façon, vous pourrez appeler ultérieurement votre code injecté.

Assurez-vous que vous comprenez que ce node.innerHTML n'est pas la même chose que node.appendChild . Vous voudrez peut-être passer un peu de temps sur la référence du client Javascript pour plus de détails et le DOM. J'espère que ce qui suit vous aidera ...

L'injection d'échantillon fonctionne:

<html>
<head>
<title>test</title>
<script language="javascript" type="text/javascript">
    function doOnLoad(){
        addScript('inject',"function foo(){ alert('injected'); }");
    }


    function addScript(inject,code){
        var _in = document.getElementById('inject');
        var scriptNode = document.createElement('script');
        scriptNode.innerHTML = code;
        _in.appendChild(scriptNode);
    }

</script>
</head>
<body onload="doOnLoad();">
    <div id="header">some content</div>
    <div id="inject"></div>
    <input type="button" onclick="foo(); return false;" value="Test Injected" />
</body>
</html>

Cordialement,

Andreas
la source
2
Enfin quelqu'un qui explique en fait un peu le problème plutôt que toutes les autres try this, look how clever I amréponses. Mérite un UV, il a le mien.
RiggsFolly
Je uv ceci parce que c'est le moyen le plus simple d'injecter du code javascript qui s'exécute après l'injection. Je ne saisis seulement pas la différence entre l'ajout avec innerHTML qui ne s'exécute pas, et la manière ci-dessus avec appendChild qui s'exécute. J'ai utilisé cela avec succès pour créer une page dynamique avec un script à partir de zéro avec socket.io
wetlip
2
var _in = document.getElementById(inject);, Je pense.
Ron Burk
21

Version ES6 simplifiée de la réponse de @ joshcomley avec un exemple.

Pas de JQuery, pas de bibliothèque, pas d'évaluation, pas de changement DOM, juste du Javascript pur.

http://plnkr.co/edit/MMegiu?p=preview

var setInnerHTML = function(elm, html) {
  elm.innerHTML = html;
  Array.from(elm.querySelectorAll("script")).forEach( oldScript => {
    const newScript = document.createElement("script");
    Array.from(oldScript.attributes)
      .forEach( attr => newScript.setAttribute(attr.name, attr.value) );
    newScript.appendChild(document.createTextNode(oldScript.innerHTML));
    oldScript.parentNode.replaceChild(newScript, oldScript);
  });
}

Usage

$0.innerHTML = HTML;    // does *NOT* run <script> tags in HTML
setInnerHTML($0, HTML); // does run <script> tags in HTML
allenhwkim
la source
1
typo: le nom de la fonction n'est setInnerHtmlpassetInnerHTML
pery mimon
Notez que dans le plnkr qui est lié, le nom de la fonction est setInnerHTMLmais il est appelé à setInnerHtmlpartir de la runBfonction. Par conséquent, l'exemple ne fonctionne pas
danbars
16

Essayez cet extrait:

function stripAndExecuteScript(text) {
    var scripts = '';
    var cleaned = text.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(){
        scripts += arguments[1] + '\n';
        return '';
    });

    if (window.execScript){
        window.execScript(scripts);
    } else {
        var head = document.getElementsByTagName('head')[0];
        var scriptElement = document.createElement('script');
        scriptElement.setAttribute('type', 'text/javascript');
        scriptElement.innerText = scripts;
        head.appendChild(scriptElement);
        head.removeChild(scriptElement);
    }
    return cleaned;
};


var scriptString = '<scrip' + 't + type="text/javascript">alert(\'test\');</scr' + 'ipt><strong>test</strong>';
document.getElementById('element').innerHTML = stripAndExecuteScript(scriptString);
Fantactuka
la source
oui, cette méthode fonctionne mais vous obtiendrez des erreurs si vous avez des commentaires ou des consoles.logs, alors faites attention à cela, vous pouvez également modifier pour tenir compte des modules var modules = [] var nettoyé = text.replace (/ <script ([^> ] *)> ([\ s \ S] *?) <\ / script> / gi, function (m, tags, script) {if (/type="module"/.test(tags)) {modules.push (script) return} scripts + = script + '\ n' return ''})
zavr
13
function insertHtml(id, html)  
{  
   var ele = document.getElementById(id);  
   ele.innerHTML = html;  
   var codes = ele.getElementsByTagName("script");   
   for(var i=0;i<codes.length;i++)  
   {  
       eval(codes[i].text);  
   }  
}  

Cela fonctionne dans Chrome dans mon projet

Bruce
la source
Rapide et joli. Je vous remercie.
Jorge Fuentes González
C'est tout! Je vous remercie.
Floris
7

Une solution sans utiliser "eval":

var setInnerHtml = function(elm, html) {
  elm.innerHTML = html;
  var scripts = elm.getElementsByTagName("script");
  // If we don't clone the results then "scripts"
  // will actually update live as we insert the new
  // tags, and we'll get caught in an endless loop
  var scriptsClone = [];
  for (var i = 0; i < scripts.length; i++) {
    scriptsClone.push(scripts[i]);
  }
  for (var i = 0; i < scriptsClone.length; i++) {
    var currentScript = scriptsClone[i];
    var s = document.createElement("script");
    // Copy all the attributes from the original script
    for (var j = 0; j < currentScript.attributes.length; j++) {
      var a = currentScript.attributes[j];
      s.setAttribute(a.name, a.value);
    }
    s.appendChild(document.createTextNode(currentScript.innerHTML));
    currentScript.parentNode.replaceChild(s, currentScript);
  }
}

Cela clone essentiellement la balise de script, puis remplace la balise de script bloquée par la balise nouvellement générée, permettant ainsi l'exécution.

Joshcomley
la source
3

scriptNode.innerHTML = coden'a pas fonctionné pour IE. La seule chose à faire est de remplacer par scriptNode.text = codeet cela fonctionne bien

Jorge
la source
3

Il est plus facile d'utiliser jquery $(parent).html(code)au lieu de parent.innerHTML = code:

var oldDocumentWrite = document.write;
var oldDocumentWriteln = document.writeln;
try {
    document.write = function(code) {
        $(parent).append(code);
    }
    document.writeln = function(code) {
        document.write(code + "<br/>");
    }
    $(parent).html(html); 
} finally {
    $(window).load(function() {
        document.write = oldDocumentWrite
        document.writeln = oldDocumentWriteln
    })
}

Cela fonctionne également avec les scripts qui utilisent document.write et les scripts chargés via l' srcattribut. Malheureusement, même cela ne fonctionne pas avec les scripts Google AdSense.

iirekm
la source
1
Qu'est-ce qui vous fait dire que c'est plus facile? Ce n'est même pas plus court. Je pense toujours que la surutilisation de jQuery est une mauvaise idée.
Manngo
2

Faites simplement:

document.body.innerHTML = document.body.innerHTML + '<img src="../images/loaded.gif" alt="" onload="alert(\'test\');this.parentNode.removeChild(this);" />';
Lambder
la source
1
ressemble à une idée de génie
pery mimon
0

Vous pouvez jeter un œil à ce post . Le code pourrait ressembler à ceci:

var actualDivToBeUpdated = document.getElementById('test');
var div = document.createElement('div');
div.innerHTML = '<script type="text/javascript">alert("test");<\/script>';
var children = div.childNodes;
actualDivToBeUpdated.innerHTML = '';
for(var i = 0; i < children.length; i++) {
    actualDivToBeUpdated.appendChild(children[i]);
}
Darin Dimitrov
la source
0

Grâce au script de Larry, qui fonctionnait parfaitement bien dans IE10, voici ce que j'ai utilisé:

$('#' + id)[0].innerHTML = result;
$('#' + id + " script").each(function() { this.text = this.text || $(this).text();} );
AxD
la source
0

Prolongement de Larry. Je l'ai fait rechercher récursivement tout le bloc et les nœuds enfants.
Le script appellera désormais également des scripts externes spécifiés avec le paramètre src. Les scripts sont ajoutés à l'en-tête au lieu d'être insérés et placés dans l'ordre dans lequel ils sont trouvés. Les scripts de commande sont donc spécifiquement préservés. Et chaque script est exécuté de manière synchrone, de la même manière que le navigateur gère le chargement initial du DOM. Donc, si vous avez un bloc de script qui appelle jQuery depuis un CDN et que le nœud de script suivant utilise jQuery ... Pas de problème! Oh et j'ai étiqueté les scripts ajoutés avec un identifiant sérialisé basé sur ce que vous avez défini dans le paramètre de balise afin que vous puissiez trouver ce qui a été ajouté par ce script.

exec_body_scripts: function(body_el, tag) {
    // Finds and executes scripts in a newly added element's body.
    // Needed since innerHTML does not run scripts.
    //
    // Argument body_el is an element in the dom.

    function nodeName(elem, name) {
        return elem.nodeName && elem.nodeName.toUpperCase() ===
              name.toUpperCase();
    };

    function evalScript(elem, id, callback) {
        var data = (elem.text || elem.textContent || elem.innerHTML || "" ),
            head = document.getElementsByTagName("head")[0] ||
                      document.documentElement;

        var script = document.createElement("script");
        script.type = "text/javascript";
        if (id != '') {
            script.setAttribute('id', id);
        }

        if (elem.src != '') {
            script.src = elem.src;
            head.appendChild(script);
            // Then bind the event to the callback function.
            // There are several events for cross browser compatibility.
            script.onreadystatechange = callback;
            script.onload = callback;
        } else {
            try {
                // doesn't work on ie...
                script.appendChild(document.createTextNode(data));      
            } catch(e) {
                // IE has funky script nodes
                script.text = data;
            }
            head.appendChild(script);
            callback();
        }
    };

    function walk_children(node) {
        var scripts = [],
          script,
          children_nodes = node.childNodes,
          child,
          i;

        if (children_nodes === undefined) return;

        for (i = 0; i<children_nodes.length; i++) {
            child = children_nodes[i];
            if (nodeName(child, "script" ) &&
                (!child.type || child.type.toLowerCase() === "text/javascript")) {
                scripts.push(child);
            } else {
                var new_scripts = walk_children(child);
                for(j=0; j<new_scripts.length; j++) {
                    scripts.push(new_scripts[j]);
                }
            }
        }

        return scripts;
    }

    var i = 0;
    function execute_script(i) {
        script = scripts[i];
        if (script.parentNode) {script.parentNode.removeChild(script);}
        evalScript(scripts[i], tag+"_"+i, function() {
            if (i < scripts.length-1) {
                execute_script(++i);
            }                
        });
    }

    // main section of function
    if (tag === undefined) tag = 'tmp';

    var scripts = walk_children(body_el);

    execute_script(i);
}
BadOPCode
la source
0

Essayez ceci, cela fonctionne pour moi sur Chrome, Safari et Firefox:

var script = document.createElement('script');
script.innerHTML = 'console.log("hi")';
document.body.appendChild(script); 
--> logs "hi"

Une chose à noter cependant, c'est que le script imbriqué div suivant ne fonctionnera PAS:

var script = document.createElement('div');
script.innerHTML = '<script>console.log("hi")</script>';
document.body.appendChild(script);
--> doesn't log anything

Pour qu'un script s'exécute, il doit être créé en tant que nœud puis ajouté en tant qu'enfant. Vous pouvez même ajouter un script à l'intérieur d'un div précédemment injecté et il s'exécutera (j'ai déjà rencontré cela lorsque j'essayais de faire fonctionner le code du serveur publicitaire):

var div = document.createElement('div');
div.id = 'test-id';
document.body.appendChild(div);
var script = document.createElement('script');
script.innerHTML = 'console.log("hi")';
document.getElementById('test-id').appendChild(script);
--> logs "hi"
Trev14
la source
0

Expansion de la réponse de Lambder

document.body.innerHTML = '<img src="../images/loaded.gif" alt="" > onload="alert(\'test\');this.parentNode.removeChild(this);" />';

Vous pouvez utiliser une image base64 pour créer et charger votre script

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAADUlEQVQYV2P4//8/AwAI/AL+iF8G4AAAAABJRU5ErkJggg=="
    onload="var script = document.createElement('script');  script.src = './yourCustomScript.js'; parentElement.append(script);" />

Ou si vous en avez un, Iframevous pouvez l'utiliser à la place

<iframe src='//your-orginal-page.com' style='width:100%;height:100%'
    onload="var script = document.createElement('script');  script.src = './your-coustom-script.js'; parentElement.append(script);"
    frameborder='0'></iframe>
pery mimon
la source
0

J'avais besoin de quelque chose de similaire, mais j'avais besoin que le script reste ou soit recréé au même endroit que le script d'origine, car mon script cible l'emplacement de la balise de script dans le DOM pour créer / cibler des éléments. J'ai également rendu le script récursif pour m'assurer qu'il fonctionne également s'il est inférieur à plus d'un niveau.

REMARQUE: j'utilise constici, si vous avez un navigateur plus ancien, utilisez simplement var.

    window.exec_body_scripts = function(body_el) {
        // ref: /programming/2592092/executing-script-elements-inserted-with-innerhtml based on Larry K's answer
        // Finds and executes scripts in a newly added element's body.
        // Needed since innerHTML does not run scripts.
        //
        // Argument body_el is an element in the dom.
        const
            type__Js = 'text/javascript',
            tagName__Script = 'script',
            tagName__Script__Upper = tagName__Script.toUpperCase();
        var scripts = [], script, i;
        function evalScript(elem) {
            var parent = elem.parentNode,
                data = (elem.text || elem.textContent || elem.innerHTML || ""),
                script = document.createElement(tagName__Script);

            script.type = type__Js;
            try {
                // doesn't work on ie...
                script.appendChild(document.createTextNode(data));
            } catch (e) {
                // IE has funky script nodes
                script.text = data;
            }
            // Make sure to re-insert the script at the same position
            // to make sure scripts that target their position
            // in the DOM function as expected.
            var parent = elem.parentNode;
            parent.insertBefore(script, elem);
            parent.removeChild(elem);
        };
        // Get all scripts (recursive)
        if (typeof (document.querySelectorAll) !== typeof (void 0)) {
            document.querySelectorAll('script').forEach((scr) => { if (!scr.type || scr.type.toLowerCase() === type__Js) scripts.push(scr); });
        }
        else {
            var children_nodes = body_el.childNodes, child;
            for (i = 0; children_nodes[i]; i++) {
                child = children_nodes[i];
                if (
                    child.nodeName
                    &&
                    child.nodeName.toUpperCase() === tagName__Script__Upper
                    &&
                    (
                        !child.type
                        ||
                        child.type.toLowerCase() === type__Js
                    )
                ) {
                    scripts.push(child);
                }
                // Recursive call
                window.exec_body_scripts(child);
            }
        }
        for (i = 0; scripts[i]; i++) {
            evalScript(scripts[i]);
        }
    };
NKCSS
la source
0

Fait cette nouvelle fonction d'aide dans TypeScript, peut-être que quelqu'un l'appréciera. Si vous supprimez la déclaration de type du paramètre de script, il ne s'agira que de JS.

const evalPageScripts = () => {
  const scripts = document.querySelectorAll('script');

  scripts.forEach((script: HTMLScriptElement) => {
    const newScript = document.createElement('script');
    newScript.type = 'text/javascript';
    newScript.src = script.src;

    if (script.parentNode) {
      script.parentNode.removeChild(script);
    }

    return document.body.appendChild(newScript);
  })
};

export default evalPageScripts;

kvba
la source
-1

Essayez la fonction eval ().

data.newScript = '<script type="text/javascript">//my script...</script>'
var element = document.getElementById('elementToRefresh');
element.innerHTML = data.newScript;
eval(element.firstChild.innerHTML);

Ceci est un exemple réel d'un projet que je développe. Merci à ce post

IgniteCoders
la source
-1

Voici ma solution dans un projet récent.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Sample</title>
</head>
<body>
<h1 id="hello_world">Sample</h1>
<script type="text/javascript">
 var div = document.createElement("div");
  var t = document.createElement('template');
  t.innerHTML =  "Check Console tab for javascript output: Hello world!!!<br/><script type='text/javascript' >console.log('Hello world!!!');<\/script>";
  
  for (var i=0; i < t.content.childNodes.length; i++){
    var node = document.importNode(t.content.childNodes[i], true);
    div.appendChild(node);
  }
 document.body.appendChild(div);
</script>
 
</body>
</html>

gris
la source