4

私が読んだものから、JQueryのgetScript関数は、「globaleval」と呼ばれる関数を使用してグローバルコンテキストでスクリプトファイルをロードします。これを変更するための特定の設定またはメソッドがありますか?代わりに、呼び出し元の関数内にロードされますか?

次のコードネームを実行すると、ローカルコンテキストでスクリプトが読み込まれないため、undefinedが返されます。

    function callscript(){
        var name='fred';
    getScript(abc.js);
    }

//abc.js:
alert(name);
4

5 に答える 5

6

私は通常のJQueryajax呼び出しを使用して解決策を見つけたと思います。秘訣は、データ型を「テキスト」に設定することです。それ以外の場合は、スクリプトの場合、またはgetScriptまたは代替の.get()を使用する場合は、スクリプトが内部で自動的に実行され、グローバルコンテキストに配置されます。

 function abc(){
    var msg="ciao";
    $.ajax({
      url: 'themes/_default/system/message.js',
      success: function(data){
          eval(data);
      },
      dataType: "text"
    });
    }
    //message.js
(function() {
    alert(msg);
})();

これは予想通り「ciao」に警告します:)

誰かが「はい」と言う前に、私はevalを使用していますが、この状況では完全に問題ありません。

于 2013-02-24T05:29:31.637 に答える
1

すでにお気づきのように、これに関するドキュメントには何もありません。ソースコードを再確認したところ、基になる呼び出しには、この動作をオーバーライドするために渡すオプションがないことがわかりました。

// http://code.jquery.com/jquery-1.9.1.js
...
getScript: function( url, callback ) {
    return jQuery.get( url, undefined, callback, "script" );
},
...

私の知る限り、jQueryではスクリプトを非同期でローカルスコープにロードすることはできません。jQueryのAPIは、このように使用法を構成する他の手段を提供しません。

私はまだ他のテクニックを使ってそれがどのように可能であるかを調査しています。

于 2013-02-24T04:26:10.370 に答える
0

わかりました。これは4年後の2017年ですが、jQueryチームがこの問題に対処するのに苦労したことはないようです。私は同じ問題を抱えていましたが、これが解決策であり、ローカルコンテキストでgetScriptを使用する実際の意図された方法だと思います。私が気付いたのは、コードがローカルコンテキストでコードに対して簡単に評価される方法がないことでした。これは、jQueryがどのように進行しているかを認識していません。深く掘り下げていませんが、jQueryソースを見ると、スクリプトがドキュメントにどのように挿入されているか、それは天才であり、評価を完全に回避しています。したがって、スクリプトは、scriptタグを介してインポートされたファイルであるかのように実行されました。難しい話は抜きにして...

私は状況の逆を行うことにしました、それは何が起こっているのかをよりよく説明します。次に、問題の例に戻すことができます。

getScriptが実際に一意のIDをクエリ文字列でサーバーに送信していることに気付いた場合。彼らがドキュメントでこれについて言及しなかった理由はわかりません。これを使用して、返されたスクリプトを識別します。しかし、バックエンドで何かをしなければなりません...

let imports;

$.getScript("scripts.php?file=abc.js", (data, textStatus, jqXHR) => {
    window[jqXHR.getResponseHeader('X-scriptID')](imports);
    alert (imports.name);
});

abc.js:

imports.name = 'fred';

バックエンドは、scripts.phpを取得しているスクリプトをラップします。

// code that gets the file from  file system into var $output
$output = file_get_contents($_REQUEST['file']);

// generate a unique script function name, sort of a namespace
$scriptID = "__script" . $_REQUEST['_'];

// wrap the script in a function a pass the imports variable 
// (remember it was defined in js before this request) we will attach
// things we want to become local on to this object in script file
$output = "window.".$scriptID."=function(imports) { ".$output." };";

// set the script id so we can find this script in js           
header ("X-scriptID: " . $scriptID);

// return the output
echo $output;

jsはgetScriptを介してスクリプトを要求しますが、ファイルに直接要求するのではなく、phpスクリプトを使用してファイルの内容をフェッチします。これは、返されたデータを変更し、返されたスクリプトを識別するために使用されるヘッダーを添付できるようにするためです(これは、この方法で多くのスクリプトが要求される大きなアプリです)。

getScriptが通常どおりブラウザで返されたスクリプトを実行すると、スクリプトの実際のコンテンツは実行されず、一意の名前__script1237863498などのラッパー関数の宣言のみが実行されます(番号は、以前にそのスクリプトを要求したときにgetScriptによって指定されました) )、グローバルウィンドウオブジェクトにアタッチされます。次に、jsはその応答を使用してラッパー関数を実行し、インポートオブジェクトにプロパティを挿入します...これは、要求しているスコープに対してローカルになります。

于 2017-06-06T12:50:40.437 に答える
-2

jQueryの実装はわかりませんが、オブジェクトのプライベートプロパティであるためnameに返さundefinedれる理由があります。これを否定するには、関数呼び出しの外部で変数を宣言できます。namecallscript

var name = ''; //Declare name outside of the function
function callscript(){
  name='fred';
  getScript('abc.js'); //Shouldn't it be $.getScript? and argument should be passed as a string
}

//abc.js:
console.log(name) //Returns undefined
callscript(); //Call the script
console.log(name); //Returns "fred"
于 2013-02-24T04:21:22.310 に答える
-2
// global.js
var global1 = "I'm a global!";

// other js-file
function testGlobal () {
    alert(global1);
}
于 2013-02-24T04:11:49.657 に答える