web-dev-qa-db-ja.com

jQuery getScript関数を介して追加されたデバッグスクリプト

JQueryの$.getScript関数を介してスクリプト参照を動的に追加するページがあります。スクリプトは正常に読み込まれて実行されるので、参照が正しいことはわかっています。ただし、デバッガー(VS.Net、Firebugなど)内のコードをステップ実行できるように、スクリプトに「デバッガー」ステートメントを追加すると、機能しません。 jQueryがスクリプトをロードする方法について何かがデバッガーがファイルを見つけることを妨げているようです。

誰かがこれの回避策を持っていますか?

49
James Messinger

わかりましたので、参照されたスクリプトファイルが同じドメイン上にあるかどうかによって、$.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>
_

この後者のアプローチはnotを私がテストしたデバッガー(Visual Studio.net、Firebug、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>
_
75
James Messinger

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);
            }
        })
18
Eric Twilegar

スクリプトをデバッグして$ .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でうまく機能し、スクリプトは完全に表示され、デバッグ可能です。ありがとうございます。

14

これを試して、

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;

} 
   });
2
alexpts

Chromeでデバッグする簡単な方法があります。

1-デバッグする行にconsole.log( "something")を記述します。

2-そのログのコンソールを監視します。

sample log

3-ログの前にあるアドレスリンクをクリックします。

4-その行にブレークポイントを設定します。

2
DaNeSh

答えはすべてこのページのどこかにありますが、将来の読者のためにまとめておきたいと思います。

(動的に追加された)ファイルのダウンロードの確認

Chromeを使用すると、$。getScript( http://api.jquery.com/jQuery.getScript/ )を使用して追加されたJavascriptファイルをNetworkパネルの下に表示できますXHRタブ; JSタブの下には表示されません。

ファイルのデバッグ

1)コードにブレークポイントを設定します。他のanswers\commentsで述べたように、あなたは挿入することができます

debugger;

javaScriptコード内のステートメント。これにより、ブラウザのデバッガが呼び出されます。詳細は https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger を参照してください。

2)Source Mapを使用して、ブラウザーの[Sources]パネルに表示されるようにします(Chromeでテスト)。

//# sourceURL=whatevername.js

ファイルの最後に。 [ファイルはChromeソースパネル]の(ドメインなし)に表示されます。

参照: ブラウザのデバッガ自体で動的に読み込まれたJavaScript(jQueryを使用)をデバッグする方法 および https://developer.mozilla.org/en-US/docs/Tools/Debugger/詳細については、How_to/Use_a_source_map をご覧ください。

3)$ .getScriptをオーバーライドして、受け入れられた回答に従って常に外部参照を使用します(テストしていません)。

0
Anthony

これはOPソリューションとEricのソリューションを組み合わせたものです。 getを処理するために必要なjqueryをオーバーライドすると、常にクロスドメインが取得され、jquery promiseの実装で1つのことを壊すことなく完全に表示されます。

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
 });
}


});
0
osoblanco

多くの余分なコーディングを避けるために、これを試すことができます。 $( 'document')。ready()(またはデバッガがアクセスする他のファイル)を宣言したファイルに、次のように追加します...

$.debug = function(name) {
   var n = name;
}

デバッガーの割り当て行にブレークポイントを追加します。次に、$。getScript()でロードした他のjs-fileに追加できます...

$.debug("some string to identify this point of code");

この行が実行されると、デバッガーは停止してコマンドを待ちます。 $ .debug関数から抜け出し、それで終わりです。

0
user1904991

Firefox 38.6.0とFirebug 2.0.14では、[スクリプト]タブに移動すると、ドロップダウンメニューに_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 );
    }
},
_
0
AsGoodAsItGets