[英]Debugging scripts added via jQuery getScript function
我有一個頁面,通過jQuery的$.getScript
函數動態添加腳本引用。 腳本加載並執行正常,所以我知道引用是正確的。 但是,當我向任何腳本添加“調試器”語句以允許我在調試器(例如VS.Net,Firebug等)中單步執行代碼時,它不起作用。 似乎jQuery加載腳本的方式阻止了調試器查找文件。
有沒有人為此解決這個問題?
好的,所以事實證明$.getScript()
函數的默認實現工作方式不同,具體取決於引用的腳本文件是否在同一個域中。 外部參考如:
$.getScript("http://www.someothersite.com/script.js")
將導致jQuery創建一個外部腳本引用,可以毫無問題地進行調試。
<script type="text/javascript" src="http://www.someothersite.com/script.js"></script>
但是,如果引用本地腳本文件,例如以下任何一種:
$.getScript("http://www.mysite.com/script.js")
$.getScript("script.js")
$.getScript("/Scripts/script.js");
然后jQuery將異步下載腳本內容,然后將其添加為內聯內容:
<script type="text/javascript">{your script here}</script>
后一種方法不會與我測試(視覺Studio.net,螢火蟲,IE8調試器)任何調試工作。
解決方法是覆蓋$.getScript()
函數,以便它始終創建外部引用而不是內聯內容。 這是執行此操作的腳本。 我已經在Firefox,Opera,Safari和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>
使用JQuery 1.6(可能是1.5),您可以切換到不使用getScript,但使用jQuery.ajax()。 然后設置crossDomain:true,你將獲得相同的效果。
錯誤回調將不起作用。 所以你可能不會像下面那樣設置它。
但是,我確實設置了一個計時器並成功清除它。 所以說10秒后,如果我什么也聽不到,我認為文件很糟糕。
jQuery.ajax({
crossDomain: true,
dataType: "script",
url: url,
success: function(){
_success(_slot)
},
error: function(){
_fail(_slot);
}
})
對於那些想調試腳本並與$ .when一起使用的人(James Messinger的答案與$ .when不兼容)我建議使用這段代碼:
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();
};
所有的榮譽和榮耀都歸功於Benjamin Dumke-von der Ehe和他的文章: jQuery腳本插入及其對調試的影響
這適用於$ .when,腳本是完全可見和可調試的。 謝謝。
有一種簡單的方法可以使用Chrome進行調試。
1-在要調試的行上寫一個console.log(“something”)。
2-觀察該日志的控制台。
3-單擊日志前面的地址鏈接。
4-在該行上設置斷點。
試試這個,
jQuery.extend({
getScript: function(url, callback) {
var head = document.getElementsByTagName("head")[0];
var ext = url.replace(/.*\.(\w+)$/, "$1");
if(ext == 'js'){
var script = document.createElement("script");
script.src = url;
script.type = 'text/javascript';
} else if(ext == 'css'){
var script = document.createElement("link");
script.href = url;
script.type = 'text/css';
script.rel = 'stylesheet';
} else {
console.log("Неизветсное расширение подгружаемого скрипта");
return false;
}
// 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;
}
});
為了避免大量的額外編碼,你可以試試這個。 在您聲明$('document').ready()( 或調試器將訪問的任何其他文件 )的文件中 ,添加類似...
$.debug = function(name) {
var n = name;
}
在調試器的賦值行中添加斷點。 然后,在使用$ .getScript()加載的任何其他js文件中,您可以添加...
$.debug("some string to identify this point of code");
每當執行此行時,調試器將停止並等待您的命令。 退出$ .debug函數,就是這樣!
在使用Firebug 2.0.14的Firefox 38.6.0中,當我轉到“腳本”選項卡時,我在下拉菜單中看到一個條目,如jquery-1.11.1.js line 338 > eval
,其中包含已加載的腳本。 另外,看看這個版本的jQuery中的代碼,看起來內部$.getScript()
使用$.get()
和最終$.ajax()
,唯一的區別是腳本的eval()
部分,由jQuery globalEval()
函數處理:
// Evaluates a script in a global context
// Workarounds based on findings by Jim Driscoll
// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
globalEval: function( data ) {
if ( data && jQuery.trim( data ) ) {
// We use execScript on Internet Explorer
// We use an anonymous function so that context is window
// rather than jQuery in Firefox
( window.execScript || function( data ) {
window[ "eval" ].call( window, data );
} )( data );
}
},
這將OP解決方案與Eric相結合。 覆蓋必要的jquery來處理始終是crossdomain並且它們將完美地顯示而不會破壞jquery promise實現中的單個事物。
jQuery.extend({
get: function (url, data, callback, type) {
// shift arguments if data argument was omitted
if (jQuery.isFunction(data)) {
type = type || callback;
callback = data;
data = undefined;
}
return jQuery.ajax({
url: url,
type: "GET":,
dataType: type,
data: data,
success: callback,
crossDomain: true
});
}
});
所有答案都在這個頁面的某個地方,但我想總結一下未來的讀者。
檢查(動態添加)文件下載
使用Chrome,您可以在XHR標簽的“ 網絡”面板下看到使用$ .getScript( http://api.jquery.com/jQuery.getScript/ )添加的Javascript文件; 請注意它們不會出現在JS選項卡下。
調試文件
1)在代碼中設置斷點 。 如其他答案\\評論中所述,您可以插入一個
debugger;
Javascript代碼中的語句。 這將調用瀏覽器的調試器。 有關詳細信息,請參閱https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger 。
2)使用源地圖使其顯示在瀏覽器的“源”面板中(在Chrome中測試)。添加
//# sourceURL=whatevername.js
到你的文件的末尾。 [該文件顯示在Chrome源面板中的(無域)下)。
請參閱: 如何在瀏覽器的調試器本身中調試動態加載的JavaScript(使用jQuery)? 和https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map獲取更多信息。
3)覆蓋$ .getScript以始終根據接受的答案使用外部引用(我尚未測試)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.