ノードの追加script
はうまくいくはずです。これらのスクリプトはそれらを追加するコードに対して非同期的に実行されるため、次のことを順番に実行するために呼び出すコールバックを与える必要があります。例えば:
if (window.localStorage) {
// Load the local storage stuff; once loaded, it'll call
// `doTheNextThing`
var script = document.createElement('script');
script.type = "text/javascript";
script.src = /* ... the URL of the script ... */;
document.body.appendChild(script); // Or append it to `head`, doesn't matter
// and `document.body` is convenient
}
else {
// Skip loading it
setTimeout(doTheNextThing, 10);
}
function doTheNextThing() {
// ...
}
...ロード後のlocalStorage
スタッフ呼び出し用にロードしている動的スクリプト。つまり、動的にロードされたスクリプトが存在する場合は呼び出しますが、存在しない場合は上記のコードが呼び出します。上記のコードからの呼び出しを意図的に ( 経由で )非同期にしたことに注意してください。どのように呼び出されるかに関係なく、常に非同期にすることで、バグを見逃す可能性が低くなります (たとえば、同期的に呼び出されることに依存するものを追加してから、テストを忘れるなど)。 IE のマイナー チェンジ)。doTheNextThing
localStorage
doTheNextThing
setTimeout
更新:上記は、ロードしているスクリプトを制御していることを前提としていますが、そうでないことを明確にしました。その場合、スクリプトを 1 つずつロードし、それらが提供する機能 (通常は のwindow
ようなオブジェクトのプロパティwindow.jQuery
) をポーリングする必要があります。次のようなものです (テストされていません)。
// Load the script designated by `src`, poll for the appearance
// of the symbol `name` on the `window` object. When it shows
// up, call `callback`. Timeout if the timeout is reached.
function loadAndWait(src, name, timeout, callback) {
var stop, script;
// Do nothing if the symbol is already defined
if (window[name]) {
setTimeout(function() {
callback("preexisting");
}, 10);
}
else {
// Load the script
script = document.createElement('script');
script.type = "text/javascript";
script.src = src;
document.body.appendChild(script);
// Remember when we should stop
stop = new Date().getTime() + timeout;
// Start polling, long-ish initial interval
setTimeout(poll, 150);
}
function poll() {
if (window[name]) {
// Got it
callback("loaded");
}
else if (new Date().getTime() > stop) {
// Time out
callback("timeout");
}
else {
// Keep waiting, shorter interval if desired
setTimeout(poll, 75);
}
}
}
...これは、jQuery の読み込みに次のように使用します。
loadAndWait(
"http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
"jQuery",
10000, // ten seconds or whatever
function(result) {
// ...do the next one if result !== "timeout"
}
);
loadAndWait
以前の呼び出しのコールバックのそれぞれに呼び出しをネストするか、配列とカウンターを使用できます。
loadThese(
[
{ src: "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
symbol: "jQuery"
},
{
src: "http://the-next-one",
symbol: "nextSymbol"
}
],
doTheNextThing
);
function loadThese(scripts, callback) {
var index = 0;
run("okay");
function run(result) {
var entry;
if (result === "timeout") {
callback(result);
}
else if (index < scripts.length) {
entry = scripts[index++];
loadAndWait(entry.src, entry.symbol, 10000, run);
}
else {
callback("loaded");
}
}
}
そこで、各スクリプトを順番にロードするためにloadThese
使用するループを設定します。run
上記のすべては完全にすぐに使えるものであり、おそらく締めて防弾することができますが、アイデアはわかります.
トピック外ですが、私の質問は次のとおりです。実際にコードが多すぎて、それを使用してロードできないブラウザにとって問題になるのでしょうか? ファイルが非常に大きくならない限り、高度なブラウザーを使用しているユーザーの場合、実際にはサイトの速度が低下しますが、他のブラウザーでは何も得られません. 特定のサイズを下回ると、サーバーに接続してスクリプトを取得するオーバーヘッドは、スクリプトの転送と同じくらい大きな要因になります。余分なものは 50k のコードですか? それが本当に必要かどうかをテストするために、いくつかのベンチマークを行います...おそらくそうです(おそらくすでに持っているでしょう!)が、言及する価値があります...
トピック外の更新localStorage
:更新された質問では、サポートされている場合にダウンロードする 5 つの個別のスクリプトをリストします。さまざまな CDN から 5 つすべてを取得していると仮定しても、(通常の方法で行うか、上記の方法で行うかにかかわらず) 多数の個別のスクリプト リクエストがあり、それぞれを一度に 1 つずつ処理する必要があります。これは、発生するのを待っているページ読み込みのパフォーマンスの問題です。(おそらく) CDN と既存のキャッシュの利点を失うにもかかわらず、これらのスクリプトをすべて取得して結合し、結合したバージョンを 1 つのファイルでホストすることを検討するかもしれません。YUI パフォーマンスの「ルール」の「HTTP リクエストの最小化」を参照してください(私は「ガイドライン」という用語を好みますが、何でも構いません)。また、動的ロードを簡素化します。