2009-04-21 16 views
10

私はjavascriptクラスを含むdynamicllyスクリプトを読み込むスクリプトを持っています。 私は次のコードを使用して、クラスのスクリプトをロードしています:私は、その後のevalを使用して新しいクラスを作成しようとしている動的スクリプトの読み込み同期

var head = document.getElementsByTagName("head")[0]; 
var script = document.createElement("script"); 
script.type = "text/javascript"; 
script.src = "myscript.js"; 
head.appendChild(script); 

を:

var classObj = eval(" new MyClass()"); 

問題はevalののコードがあるということですスクリプトがメモリに読み込まれて実行されていてエラーが発生するMyClass is undefined.

これらのイベントを同期させる方法はありますか?私はそれからクラスを割り当て始める前に、スクリプトが完全にメモリにロードされていることを確認する必要があります。

+0

この関連の答えをチェックアウト:** [動的に追加されたスクリプトタグの読み込み順序](http://stackoverflow.com/a/38840724/2247494)** – jherax

答えて

0

DOMに<script>要素を追加すると、ブラウザは実際にスクリプトを実際に評価するでしょうか?私はどこか読んでいないという漠然とした記憶を持っていますが、おそらく昨日、あまりにも多くのオーブンクリーナーを吸ってしまいました。

+1

はい。オンデマンドJavaScriptと呼ばれています。 あなたはそれについてもっと読むことができます:http://www.webreference.com/programming/javascript/rg29/ – Amir

0

アミール、それはあたかもスクリプトがサーバーに座っているかのように見えます。つまり、ブラウザによってロードされていないと思います。したがって、head.appendChild(script);nullが追加されています。サーバーから名前を呼び出すだけでスクリプトを取得することはできません。スクリプトを要求し、ページに挿入するか、ajaxを使用するか、または<script>タグを使用してスクリプトを読み込む必要があります。

+0

私はそれを最初に考えました。私はそれをdebbugedし、スクリプトが数ミリ秒後に利用可能になっているのを見た。私はアラートを追加しました( "私はロードされました")。スクリプトに入れて、それが実行されるのを見た。 – Amir

+0

-1すぐにスクリプト_element_を追加しますが、_code_を非同期に_code_スクリプトをロードして実行します。そのため、クラスは即座に利用できません。 –

1

jQuery(JavaScriptライブラリ)getScriptを使用すると、スクリプトを非同期に読み込むことができます。コールバック関数を使用してオブジェクトを作成します。例:あなたが取得script.readyStateプロパティをチェックし、Web標準、またはonreadystatechangeに準拠したブラウザで、オンロードの方法のいずれかにイベントハンドラをアタッチする必要が

$.getScript("script.js", function() { 
    var classObj = new MyClass(); 
}); 
+0

'getScript()'ドキュメントによれば、これは信頼できません。「コールバックはスクリプトがロードされても必ず実行されるとは限りません。 –

5

等しい「ロードされた」または「完全な」 、Internet Explorerで。

スクリプトがロードされたことを通知される前に、宣言されていないオブジェクトや関数、プロパティにまだアクセスしようとしていない可能性があります。

var appendScript = function(parent, scriptElt, listener) { 
    // append a script element as last child in parent and configure 
    // provided listener function for the script load event 
    // 
    // params: 
    // parent - (DOM element) (!nil) the parent node to append the script to 
    // scriptElt - (DOM element) (!nil) a new script element 
    // listener - (function) (!nil) listener function for script load event 
    // 
    // Notes: 
    // - in IE, the load event is simulated by setting an intermediate 
    //  listener to onreadystate which filters events and fires the 
    //  callback just once when the state is "loaded" or "complete" 
    // 
    // - Opera supports both readyState and onload, but does not behave in 
    //  the exact same way as IE for readyState, e.g. "loaded" may be 
    //  reached before the script runs. 

    var safelistener = catchError(listener,'script.onload'); 

    // Opera has readyState too, but does not behave in a consistent way 
    if (scriptElt.readyState && scriptElt.onload!==null) { 
     // IE only (onload===undefined) not Opera (onload===null) 
     scriptElt.onreadystatechange = function() { 
     if (scriptElt.readyState === "loaded" || 
      scriptElt.readyState === "complete") { 
      // Avoid memory leaks (and duplicate call to callback) in IE 
      scriptElt.onreadystatechange = null; 
      safelistener(); 
     } 
     }; 
    } else { 
     // other browsers (DOM Level 0) 
     scriptElt.onload = safelistener; 
    } 
    parent.appendChild(scriptElt); 
}; 

ニーズに適合させるために、あなたがキャッチし、エラーを記録するために、リスナーをラップcatchErrorへの呼び出しを置き換えることがあります。ここでは

は私の Javascript library, bezen.orgにモジュール bezen.dom.jsから抽出された例の関数であり、 、および修正機能を使用します。あなたは、外部スクリプトを編集することができるように見えるので

var appendScript = function(parent, scriptElt, listener) { 
    // append a script element as last child in parent and configure 
    // provided listener function for the script load event 
    // 
    // params: 
    // parent - (DOM element) (!nil) the parent node to append the script to 
    // scriptElt - (DOM element) (!nil) a new script element 
    // listener - (function) (!nil) listener function for script load event 
    // 
    // Notes: 
    // - in IE, the load event is simulated by setting an intermediate 
    //  listener to onreadystate which filters events and fires the 
    //  callback just once when the state is "loaded" or "complete" 
    // 
    // - Opera supports both readyState and onload, but does not behave in 
    //  the exact same way as IE for readyState, e.g. "loaded" may be 
    //  reached before the script runs. 

    var safelistener = function(){ 
     try { 
     listener(); 
     } catch(e) { 
     // do something with the error 
     } 
    }; 

    // Opera has readyState too, but does not behave in a consistent way 
    if (scriptElt.readyState && scriptElt.onload!==null) { 
     // IE only (onload===undefined) not Opera (onload===null) 
     scriptElt.onreadystatechange = function() { 
     if (scriptElt.readyState === "loaded" || 
      scriptElt.readyState === "complete") { 
      // Avoid memory leaks (and duplicate call to callback) in IE 
      scriptElt.onreadystatechange = null; 
      safelistener(); 
     } 
     }; 
    } else { 
     // other browsers (DOM Level 0) 
     scriptElt.onload = safelistener; 
    } 
    parent.appendChild(scriptElt); 
}; 
2

を(アラートでそれをテストしたので)、なぜちょうどそのスクリプトにこのコードを入れていませんか?

load_complete(); 
:あなたは(多分余分なコードが生成されるか、最初のファイルは、おそらく共有されている)ことを行うことができない場合

、ちょうどあなたがこのようにロードしているスクリプトの最後に、関数呼び出しを追加その後、

とその機能であなたの余分なコードを置く:

function load_complete() { 
    var classObj = eval(" new MyClass()"); 
} 

それはonloadイベントトリガーのいずれかの種類よりもずっと簡単かつ確実なのです。また、jsファイルが共有されている場合は、それを使用するすべてのページで異なるload_complete関数を使用できます(空であっても必ずload_completeを定義してください)。

1

私は、これは実際にあなたがこのような外部スクリプト別のスクリプトブロックを使用して、外部スクリプトやコードを読み込むコードを配置することによって改善することができると信じている:

<script> 
var head = document.getElementsByTagName("head")[0]; 
var script = document.createElement("script"); 
script.type = "text/javascript"; 
script.src = "myscript.js"; 
head.appendChild(script); 

//this is in the same script block so it wouldn't work 
//var classObj = eval(" new MyClass()"); 
</script> 

<script> 
//this is in a separate script block so it will work 
var classObj = eval(" new MyClass()"); 
</script> 
関連する問題