Сценарии отладки, добавленные с помощью функции jQuery getScript
У меня есть страница, которая динамически добавляет ссылки script через функцию jQuery $.getScript
. Сценарии загружаются и выполняются отлично, поэтому я знаю, что ссылки верны. Однако, когда я добавляю оператор "отладчик" к любому из скриптов, чтобы позволить мне выполнить код в отладчике (например, VS.Net, Firebug и т.д.), Он не работает. Похоже, что что-то о том, как загружает сценарии jQuery, мешает отладчикам находить файлы.
Есть ли у кого-нибудь обход?
Ответы
Ответ 1
Итак, получается, что реализация функции $.getScript()
по умолчанию работает по-разному в зависимости от того, находится ли указанный файл script в том же домене или нет. Внешние ссылки, такие как:
$.getScript("http://www.someothersite.com/script.js")
заставит jQuery создать внешнюю ссылку script, которая может быть отлажена без проблем.
<script type="text/javascript" src="http://www.someothersite.com/script.js"></script>
Однако, если вы ссылаетесь на локальный файл script, например, любой из следующих:
$.getScript("http://www.mysite.com/script.js")
$.getScript("script.js")
$.getScript("/Scripts/script.js");
то jQuery будет загружать контент script асинхронно, а затем добавить его как встроенный контент:
<script type="text/javascript">{your script here}</script>
Этот последний подход не работает с любым отладчиком, который я тестировал (Visual Studio.net, Firebug, IE8 Debugger).
Обходной путь заключается в переопределении функции $.getScript()
, чтобы он всегда создавал внешнюю ссылку, а не встроенный контент. Для этого используется script. Я тестировал это в 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>
Ответ 2
С 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);
}
})
Ответ 3
Для тех, кто хотел бы отлаживать скрипты и использовать их с помощью $.when(ответ Джеймса Мессингера не работает с $.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();
};
Все кредиты и слава идут к Бенджамину Думке-фон-дер-Эхе и его статье: вставка jQuery script и ее последствия для отладки
Это хорошо работает с $.when и script полностью виден и отлаживается.
Спасибо.
Ответ 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;
}
});
Ответ 5
Существует простой способ отладить его с помощью Chrome.
1- Напишите console.log( "что-то" ) в строке, которую вы хотите отлаживать.
2- Следите за консолью для этого журнала.
![sample log]()
3- Нажмите на адресную ссылку перед журналом.
4- Установите точку останова на этой строке.
Ответ 6
Чтобы избежать большого количества дополнительного кода, вы можете попробовать это. В файле, в котором вы указали свой $('document'). Ready() (или любой другой файл, к которому будет работать ваш отладчик), добавьте что-то вроде...
$.debug = function(name) {
var n = name;
}
Добавьте точку останова в строку назначения в отладчике. Затем в любом другом js файле, который вы загружаете с помощью $.getScript(), вы можете добавить...
$.debug("some string to identify this point of code");
Всякий раз, когда эта строка выполняется, ваш отладчик останавливается и ждет вашей команды. Выйдите из функции $.debug и это!
Ответ 7
В Firefox 38.6.0 с Firebug 2.0.14, когда я перехожу на вкладку Script, я вижу запись в раскрывающемся меню типа jquery-1.11.1.js line 338 > eval
и содержит загруженный script. Плюс, глядя на код в этой версии jQuery, он выглядит как внутри $.getScript()
использует $.get()
и в конечном итоге $.ajax()
, единственная разница - это часть eval()
для script, которая обрабатывается Функция 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 );
}
},
Ответ 8
Это объединяет решение OP с решением Эрика. Переопределите необходимый jquery, чтобы лечить, как всегда, crossdomain, и они отлично появятся, не сломав единственную вещь в реализации обещания jquery.
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
});
}
});
Ответ 9
Все ответы на этой странице где-то, но я хотел бы подвести итог для будущих читателей.
Проверка (динамически добавляемого) файла загрузки
Используя Chrome, вы можете видеть файлы Javascript, добавленные с помощью $.getScript(http://api.jquery.com/jQuery.getScript/) на панели "Сеть" на вкладке XHR; обратите внимание, что они не отображаются на вкладке 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, чтобы всегда использовать внешнюю ссылку согласно принятому ответу (я не проверял).