1

I am appending a script tag, along with a bunch of other html, to my current document, retrieved from an ajax call. For some reason the script is not running

//Response handling function
function(responseText){
    document.getElementById('reportContainer').insertAdjacentHTML('afterbegin',responseText);
}

An example of responseText's contents:

<h2>You are <em class="won">victorious</em>!</h2>
<h3>Earnings</h3>
... 
<script>
    alert('dgd');
</script>

All the html is getting applied to the document, including the script, but it is not running, I don't get this alert popping. What may be causing this?

php_nub_qq
  • 15,199
  • 21
  • 74
  • 144

3 Answers3

1

Check the following snippet and call the function as

var newEle = document.querySelector("#reportContainer");
exec_body_scripts(newEle);

Function

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]);
  }
};
Rashmin Javiya
  • 5,173
  • 3
  • 27
  • 49
0

It won't execute when you push it into the DOM in this way. Can you use jQuery? It will execute it:

$('#reportContainer').append('<script type="text/javascript">alert(123);</script>');
Adrian Lynch
  • 8,237
  • 2
  • 32
  • 40
  • OP has not mention `jquery` tag in answer – Rashmin Javiya Jun 14 '14 at 16:57
  • I thought `insertAdjacentHTML` is doing exactly that - converting string to DOM objects? I don't use jQuery – php_nub_qq Jun 14 '14 at 16:57
  • Then you won't be able to do it as the browsers don't execute the script. Under the hood, jQuery does. It most likely parses the string you're attempting to insert and eval()s it. Can you use jQuery? – Adrian Lynch Jun 14 '14 at 17:01
0

What you get from ajax call is plain text or XML that can be inserted into DOM as HTML fragment, but all javascript code is explicitly forbidden for security reasons. There are plenty of choices to workaround this situation - from extracting part in the responseText and using eval method (not recommended, bad practice) to using of jQuery.load method.

Borys Generalov
  • 2,255
  • 17
  • 19