0

I'm using eval() to execute all <script> tags after total rewrite of a div (whose code is loaded via an XMLHttpRequest):

var arr = document.getElementById('idOfDIV').getElementsByTagName('script');
         for (var n = 0; n < arr.length; n++){
                try {
                 eval(arr[n].innerHTML);
                } catch(err) {
                console.log(err);
                }
        }

It works well for inline-scripts, but has no effect on scripts like:

<script src="/path/to/externalScript.js"></script>

How come? Can I "force" the browser to load and execute also the external scripts?

NOTE: As I noted, the question may seems "strange", regarding the fact that eval() executes a string as javascript. What I need to do, is the force the browser to load external scripts contained in "pasted" DOM, and execute them.

10
  • 1
    um you can't really do that since the script tags don't have the source in the HTML. you could add the script tags again but that could cause a lot of leaks. Commented Jan 23, 2015 at 13:43
  • 1
    Remember: eval() is evil Commented Jan 23, 2015 at 13:43
  • 2
    I'm not clear what you're trying to do -- eval() runs a string as executable JavaScript code, it doesn't do anything with HTML tags. If you were using jQuery, I'd suggest the $.getScript() method. Commented Jan 23, 2015 at 13:45
  • @Logard: I know; but in this case is my only option. Commented Jan 23, 2015 at 13:46
  • @Blazemonger: You're right, I'm updating the question with a note Commented Jan 23, 2015 at 13:47

2 Answers 2

3

This tag :

<script src="/path/to/externalScript.js"></script>

has empty innerHTML, so you cant eval the content

What you could do is to check if the script has an src attribute, and add a script tag in the head with this src :

function addHeadScript = function(src){
    var head = document.getElementsByTagName("head")[0];
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = src;
    head.appendChild(script);
}

...


for (var n = 0; n < arr.length; n++){
    if (arr[n].src != ""){
        addHeadScript(arr[n].src);
    }
    else {
        // Evaluate the script `innerHTML`   OR
        // Create a script tag in the head and set it's content equal to arr[n].innerHTML
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

Here's one thing you could do:

var html = "Some html with a script <script>alert('test');</script>";

var frag = parsePartialHtml(html);

fixScriptsSoTheyAreExecuted(frag);


document.body.appendChild(frag);


function fixScriptsSoTheyAreExecuted(el) {
  var scripts = el.querySelectorAll('script'),
      script, fixedScript, i, len;

  for (i = 0, len = scripts.length; i < len; i++) {
    script = scripts[i];

    fixedScript = document.createElement('script');
    fixedScript.type = script.type;
    if (script.innerHTML) fixedScript.innerHTML = script.innerHTML;
    else fixedScript.src = script.src;
    fixedScript.async = false;

    script.parentNode.replaceChild(fixedScript, script);
  }
}


function parsePartialHtml(html) {
  var doc = new DOMParser().parseFromString(html, 'text/html'),
      frag = document.createDocumentFragment(),
      childNodes = doc.body.childNodes;

  while (childNodes.length) frag.appendChild(childNodes[0]);

  return frag;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.