14.11.06

Executing scripts with XmlHttpRequest

In the spirit of all that is Ajaxy, you may or may not have encountered yourself in a situation where you dynamically load content from the server into a container. In more advanced applications, this content also contains some JavaScript to be executed. It's not uncommon for people to be confused by scripts not executing this way.

Well, you have to explicitly execute them. A browser will only execute scripts loaded with the page or written to the page, not loaded dynamically. I'll show you the easy way and you'll never wonder again:

First, get all the scripts from your source and put your HTML where you want it.

var re_scripts = /<script([^>]*?)>([\w\W]*?)<\/script>/g;
var scripts = [];
myXhrSourceText.replace(re_scripts, function(match, attributes, script){
scripts.push(script);
});
myDiv.innerHTML = myXhrSourceText;

Note that I'm using the replace method to iterate through the matches, since I'm assuming there can be more than one. This method is quite handy because it doesn't require another for loop to iterate since it's using a visitor.
You can also remove the scripts from your innerHTML by assigning the return of the replace function to the innerHTML, your call.

Then, execute. It's that easy.

eval(scripts.join('\n'));


Oh wait, it's not. If your script has functions and variables intended to be used by other parts of your application, they need a scope:

self.eval(scripts.join('\n'));


That's easy. Oh wait, it's not. IE doesn't work. You have to use a super special secret command "execScript":

(window.execScript || self.eval)(scripts.join('\n'));


Given the usual IE-doesn't-work-so-I-gotta-hack-this problem, the result is small and functional. Sweet!

2 comments:

nico said...

Thanks, that was useful.
Just a minor thing: I had to change

var scripts [];

to

var scripts = new Array();

Then it all works!
nico

φ said...

Ah, good catch. That should've been:
var scripts = [];