2012-03-06 15 views
3

プラグインスタイルのアーキテクチャの一環としてjavscriptをロードしていて、次のような問題がある場合は、この問題が正しいかどうかわかりません。javascriptファイルから関数を抽出することは可能ですか?

特定のノードにプラグインへの参照、そのプラグインのjsonの説明で提供されたURLごとにそのプラグインをロードしたい。説明は、次の(またはその機能的等価物)のようなものがあります:

{ 
    "pluginSrc" : "http://mysite.com/plugins/1204.js", 
    "configData" : 
    { 
     "someData", "someValue", 
     "someMoreData", "etc" 
    } 
} 

javascriptの負荷を、私は、関数名はwindowオブジェクトにとあれば存在するかどうかをチェックするonloadイベントハンドラを持っていますしたがって、その関数の新しいインスタンスを作成し、それをconfigデータに渡す(多かれ少なかれ)、この部分はいくつかの例外を除いて非常にうまく機能します。

時々、私は呼び出す必要のある関数の名前への参照がなく、jsonから取得する方法がありません。理想的なのは、スクリプトのonloadコールバックでウィンドウオブジェクトにどの関数が追加されたのかを知り、その関数のインスタンスを作成できるかどうかです。これは可能ですか?私は現代のブラウザ、特にWebkitについて心配する必要があります。申し訳ありませんが、質問が明確でない場合は、私は明確にすることができますが、最小限の例に達するために書くべきコードがたくさんあるので、フィドルを作成するのは難しいかもしれません。

私は今のところ考えていることは

function MediaAnalytics(){}; 
var LoadedClass = MediaAnalytics; 

、スクリプトがロードされたときにちょうどLoadedClassのインスタンスを作成するようにロードされたスクリプトファイルでグローバル変数のいくつかの種類を作成することですが、これは及ばない私はいつもプラグインを書いているわけではないので、万能薬の。

EDIT:これらのスクリプトは、ほとんど同じドメインのものではありません。

+0

空白のiframeを作成し、そこにJSを読み込み、関数をiframeの 'window'からメインの' window'にコピーするとどうなりますか? (私はそれがうまくいくかどうか分かりませんが、そこに投げ込むだけです) –

+1

興味深い考え方です。残念ながら、このプロジェクトはphonegap経由でAndroid/iPhoneにエクスポートされ、iframeは私がむしろ避けたいすべての種類の問題を引き起こす可能性があります。しかし、素晴らしい提案! – Shane

答えて

2

スクリプトファイルの読み込み方法を指定していません。私はあなたがonloadハンドラのスクリプトテキストを取得することを願っています。

とにかく私はjQuery.getScriptを使ってこれを行う方法を説明しています。これで成功ハンドラのスクリプトテキストはdataとなります。したがって、これを使用してロードされたFunctionを取得できます。

スクリプトファイルが動的であるとします。JS

function MediaAnalytics(){}; 

が含まれていることがここでNewFunctiongetScript

$.getScript("dynamic.js", function (data, textStatus, jqxhr) { 
    var NewFunction; 
    eval("NewFunction = " + data); 
    alert(NewFunction.name); // here you will get alert showing MediaAnalytics 
}); 

を使用して負荷がMediaAnalyticsです。 getScriptは、それを実行してウィンドウオブジェクトに追加した後に成功ハンドラを呼び出すので、スクリプトの2回目の実行になります。具体的にnew NewFunction()をインスタンス化することができます。あなたがevalを使用して好まない場合は、別の方法は、これは(を機能MediaAnalyticsを警告する

$.getScript("dynamic.js", function (data, textStatus, jqxhr) { 
    alert(data.match(/function(.*)\(/)); 
}); 

関数の名前を見つけるために正規表現を使用している

match配列を返します。の名前を関数はそれから取得することができます。

あなたは、正確な関数名を抽出し、ウィンドウオブジェクトのプロパティを取得するために、より良い正規表現を使用することができます。

EDIT:(jqueryなし)

また、スクリプトをテキストとして読み込んで、onloadハンドラのスクリプトタグとしてウィンドウに追加することもできます。プラグインスクリプトがあなたのものでなくても、あなたのトリックを使うことができます。

var dynamicjs = "function MediaAnalytics(){};"; // script loaded as text 

var modified = "LoadedClass = " + dynamicjs; 

var head= document.getElementsByTagName('head')[0]; 
var script= document.createElement('script'); 
script.type= 'text/javascript'; 
script.textContent= modified; // innerText in some browsers 
head.appendChild(script); 

alert(LoadedClass); // LoadedClass is MediaAnalytics 
+0

輝かしい。今それを試みるつもりです。私はそこにいくつかの柔軟性があるので、負荷方法に過度に特化したくありませんでした。 – Shane

+0

httpスニッファで応答が表示されていますが、「データ」が未定義のままトレースされています。 http://jsfiddle.net/hyperthalamus/x274C/その理由は何ですか? – Shane

+0

これはそれを行うにはかなり良い方法でなければなりません –

1

jsonに入力関数の名前が必要になるようにすることをお勧めします。それは私の意見でそれについて行くために、少なくともハッキーな方法だろう。

ただし、試みることができるのは、windowのすべてのプロパティを繰り返し処理することです。スクリプトをロードした後でwindowに新しい関数が見つかった場合は、そのスクリプトがロードされたと仮定できます。このような

何か..

var windowMembers = []; 
function loadScript() { 
    for(var m in window) { 
     windowMembers.push(m); 
    } 

    //load your new script 
    //some code here to load the script 

    //put an onload handler... 
    s.onload = function() { 
     for(var m in window) { 
      if(windowMembers.indexOf(m) == -1) { 
       //window[m] was added after the script loading began 
       //call it: 
       window[m]('blah blah'); 
      } 
     } 
    } 
} 

安全のために新しいプロパティが関数である場合は、必要に応じて例えば、チェックすることができます。

if(typeof window[m] == 'function') 
+0

これは私がこれまで見てきた最も近いものだと思います。スクリプトが読み込まれる直前に実行される "s"に追加できるコールバックはありますか?私が持っている問題の1つは、これは大きなコードベースで、プラグインは誰がどこから知っているのか、ウィンドウレベルの関数を作成する他のコンポーネントやプラグインがあることを確信しています。スクリプトがインスタンス化される直前にそれをキャプチャする方法があれば、それはうまくいくと思います。 – Shane

+0

プラグインが別のプラグインから関数をオーバーライドするとどうなりますか? –

+0

私はそのクラスの新しいインスタンスを作成できないと思います。既存のインスタンスにどうしたらよいかわからない。可能な限り、それは環境に応じて起こる可能性は低いですし、そうであれば、opsの誰かが問題を突き止める4-5時間を失う可能性があります。 :) – Shane

関連する問題