views:

41

answers:

3

Based on a click event on the page, via ajax I fetch a block of html and script, I am able to take the script element and append it to the head element, however WebKit based browsers are not treating it as script (ie. I cannot invoke a function declared in the appended script).

Using the Chrome Developer Tools I can see that my script node is indeed there, but it shows up differently then a script block that is not added dynamically, a non-dynamic script has a text child element and I cannot figure out a way to duplicate this for the dynamic script.

Any ideas or better ways to be doing this? The driving force is there is potentially a lot of html and script that would never be needed unless a user clicks on a particular tab, in which case the relevant content (and script) would be loaded. Thanks!

+2  A: 

You could try using jQuery... it provides a method called .getScript that will load the JS dinamically in the proper way. And it works fine in all well known browsers.

Cristian
I thought about that, I was trying to keep all the html and related script inside a single template though and not have to separate them into two pieces, might not have a choice it seems.
whitey
+1  A: 

How about calling eval() on the content you receive from the server? Of course, you have to cut off the <script> and </script> parts.

naivists
I tried that, it is easy to get just the script content using the .textContent property, and I can see that I have the function inside a var, but eval has no effect!?!
whitey
@whitey - Can you post some code demonstrating what you're trying to do? `eval()` should work. You may also find [this article](http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html) interesting. jQuery started using his method after he wrote this, so I think it may be what you're after.
Andrew
A: 

If you're using a library like jQuery just use the built-in methods for doing this.

Otherwise you'd need to append it to the document rather than the head like this:

document.write("<scr" + "ipt type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js\"&gt;&lt;/scr" + "ipt>");

In all honesty, I have no idea why the script tag is cut like that, but a lot of examples do that so there's probably a good reason.

You'll also need to account for the fact that loading the script might take quite a while, so after you've appended this to the body you should set up a timer that checks if the script is loaded. This can be achieved with a simple typeof check on any global variable the script exports.

Or you could just do an eval() on the actual javascript body, but there might be some caveats.

Generally speaking though, I'd leave this kind of thing up to the browser cache and just load the javascript on the page that your tabs are on. Just try not to use any onload events, but rather call whatever initializers you need when the tab is displayed.

Joonas Trussmann
For inline scripts, breaking the closing `</script>` is essential because the JS parser will interpret it as the end of the present script block and not get to any of the other code after it, even if doing so raises a ton of exceptions.
Andrew