jQuery Loading Remote JavaScript

Using ajax to build a website or mobile app provides nice possibilities for a rich user experience. When asynchronly loading new pages/views without changing the navigation, background, or whatever, one needs to parse the new page and inject the new content into the current view. JavaScript linked or embedded into the new page must be processed, too.
The regular JavaScript eval() function is insufficient because it does not respect the actual context of the script. To handle this, jQuery provides the $.globalEval() function (http://api.jquery.com/jQuery.globalEval/).

To process all scripts of the remote page, one could execute the globalEval for each script element of the loaded page:

scripts.each(function () {
$.globalEval(this.text || this.textContent || this.innerHTML || '');
});

However, this code works fine in FireFox and Chrome, but it might fail in IE Version 9 and before. The typical exception thrown by the brwoser is:
"Error: Could not complete the operation due to error 80020101."
The error code indicates a problem of an ajax call, which is not totally wrong but missleading in this case. Unfortunately, the error is thrown inside the jQuery library and one needs to follow the call stack to find out, this origins in the globalEval of your own script!

The reason for this error is, the Internet Explorer 9 and before, are not able to process any code comments within the loaded JavaScript. So before executing the globalEval() method, one must clean up the JavaScript code from any code comments. This can be done by adding a replace with a regular expression filtering the code comments:

scripts.each(function () {
$.globalEval(this.text.replace(//, '$1')
|| this.textContent.replace(//, '$1')
|| this.innerHTML.replace(//, '$1')
|| '');
});

But, again, this might lead to an error. Not in IE9, but the IE8 will fail if a script element is hit which does not have it’s content within the text attribute but in the textContent or innerHTML. The reason is a call of replace() on an undefined or empty this.text reference.

To finally fix this and successfully load any remote JavaScript, you should use the code below:


scripts.each(function () {
if (this.text != undefined && this.text != '') {
$.globalEval(this.text.replace(//, '$1'));
} else if (this.textContent != undefined && this.textContent != '') {
$.globalEval(this.textContent.replace(//, '$1'));
} else if (this.innerHTML != undefined && this.innerHTML != '') {
$.globalEval(this.innerHTML.replace(//, '$1'));
}
});

A stackoverflow discussion that was helpful to build this solution:
http://stackoverflow.com/questions/7072060/after-upgrading-to-jquery-1-6-2-globaleval-throws-an-error-when-trying-to-execu

Leave a Comment