Debugging scripts added via jQuery getScript function
Ok, so it turns out that the default implementation of the $.getScript()
function works differently depending on whether the referenced script file is on the same domain or not. External references such as:
$.getScript("http://www.someothersite.com/script.js")
will cause jQuery to create an external script reference, which can be debugged with no problems.
<script type="text/javascript" src="http://www.someothersite.com/script.js"></script>
However, if you reference a local script file such as any of the following:
$.getScript("http://www.mysite.com/script.js")$.getScript("script.js")$.getScript("/Scripts/script.js");
then jQuery will download the script content asynchronously and then add it as inline content:
<script type="text/javascript">{your script here}</script>
This latter approach does not work with any debugger that I tested (Visual Studio.net, Firebug, IE8 Debugger).
The workaround is to override the $.getScript()
function so that it always creates an external reference rather than inline content. Here is the script to do that. I have tested this in Firefox, Opera, Safari, and IE 8.
<script type="text/javascript">// Replace the normal jQuery getScript function with one that supports// debugging and which references the script files as external resources// rather than inline.jQuery.extend({ getScript: function(url, callback) { var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); script.src = url; // Handle Script loading { var done = false; // Attach handlers for all browsers script.onload = script.onreadystatechange = function(){ if ( !done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete") ) { done = true; if (callback) callback(); // Handle memory leak in IE script.onload = script.onreadystatechange = null; } }; } head.appendChild(script); // We handle everything using the script element injection return undefined; },});</script>
With JQuery 1.6(maybe 1.5) you could switch to not using getScript, but using jQuery.ajax(). Then set crossDomain:true and you'll get the same effect.
The error callback will not work. So you might as well not set it up like below.
However, I do setup a timer and clear it with the success. So say after 10 seconds if I don't hear anything I assume the file was bad.
jQuery.ajax({ crossDomain: true, dataType: "script", url: url, success: function(){ _success(_slot) }, error: function(){ _fail(_slot); } })
For those who would like to debug scripts and use them with $.when (James Messinger's answer doesn't work well with $.when) I suggest to use this code:
var loadScript = function (path) { var result = $.Deferred(), script = document.createElement("script"); script.async = "async"; script.type = "text/javascript"; script.src = path; script.onload = script.onreadystatechange = function (_, isAbort) { if (!script.readyState || /loaded|complete/.test(script.readyState)) { if (isAbort) result.reject(); else result.resolve(); } }; script.onerror = function () { result.reject(); }; $("head")[0].appendChild(script); return result.promise();};
All credits and glory go to Benjamin Dumke-von der Ehe and his article: jQuery script insertion and its consequences for debugging
This works well with $.when and the script is totally visible and debuggable.Thanks.