views:

1546

answers:

3

I tried to load some scripts into a page using innerHTML with a div. It appears that the script loads into the dom, but it is never executed (at least in ff and chrome). Is there a way to have scripts execute when inserting them with innerHTML?

sample code

<!DOCTYPE html>
<html><head>
<title>test</title>
</head>
<body onload="document.getElementById('loader').innerHTML = '<script>alert(\'hi\')<\/script>'">
Shouldn't an alert saying hi appear?
<div id="loader"></div>
</body></html>
+7  A: 

You have to use eval() to execute any script code that you've inserted as DOM text.

MooTools will do this for you automatically, and I'm sure jQuery would as well. This saves a lot of hassle of parsing out <script> tags and escaping your content, as well as a bunch of other "gotchas".

Generally if you're going to eval() it yourself, you want to create/send the script code without any HTML markup such as <script>, as these will not eval() properly.

zombat
What I really want to do is to load an external script, not just eval some local script. Adding a script tag with innerHTML is much shorter than creating a script DOM element and adding it to the body, and I am trying to make my code as short as possible. Do you have to create the dom script elements and add them to the dom rather than just using something like innerHTML? Is there a way to do this with document.write from within a function?
Craig
As zombat suggest, use a Javascript framework to load the external script, don't try to reinvent the wheel. JQuery makes this extremely easy, just include JQuery and call: $.getScript(url). You can also provide a callback function that will get executed once the script is loaded.
Ariel Popovsky
Ariel is right. I appreciate trying to keep your code short, and adding a `<script>` tag with `innerHTML` might be short, but it doesn't work. It's all just plain text until it gets run through `eval()`. And sadly, `eval()` doesn't parse HTML tags, so you end up with a chain of problems.
zombat
+2  A: 

Yes you can, but you have to do it outside of the DOM and the order has to be right.

var scr = '<scr'+'ipt>alert("foo")</scr'+'ipt>';
window.onload = function(){
    var n = document.createElement("div");
    n.innerHTML = scr;
    document.body.appendChild(n);
}

...will alert 'foo'. This won't work:

document.getElementById("myDiv").innerHTML = scr;

And even this won't work, because the node is inserted first:

var scr = '<scr'+'ipt>alert("foo")</scr'+'ipt>';
window.onload = function(){
    var n = document.createElement("div");
    document.body.appendChild(n);
    n.innerHTML = scr; 
}
mwilcox
A: 

Here is a very interesting solution to your problem: http://24ways.org/2005/have-your-dom-and-script-it-too

So use this instead of script tags:

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