簡體   English   中英

調試腳本通過jQuery getScript函數添加

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM