JavaScript > 動的なscriptタグの読み込みを同期的に行う
2008年08月31日
タイトルからして何を言っているか分からないと思いますが、 JavaScriptから動的にscriptタグを追加した場合に、非同期に読み込まれるという 特徴があるのですが、これを同期的に読み込もうというお話です。
動的なscriptタグの追加
JavaScriptからscript要素を作り、追加する事で外部JSのロードを行うという処理です。 外部JSファイルの読み込みや、いわゆるJSONPとかです。
動的に追加した場合の特性として、読み込みが非同期になるというものがあります(operaは9.5からのようです)。
これは使いようによっては便利でもあり不便でもあって、 非同期読み込みの特性を利用すれば、ページ読み込みの高速化にも利用出来る(JavaScript読み込みブロック回避でページ表示を高速化する方法 | エンタープライズ | マイコミジャーナル)のですが、 ライブラリの依存関係を考慮して、順番に読み込む場合等には非同期で読み込まれると困ります。
ブックマークレットから外部ライブラリをいくつか読み込む時に困ったので、 scriptタグの読み込みを同期的に行えるようにしようという事で、少し前にライブラリを書きました。
ライブラリの紹介は後半にするとして、同期的に読み込む為のアプローチを書いていきます。
問題点
scriptタグの読み込みの完了が捕捉出来れば、コールバック関数を使って、順番にscriptタグを追加するという事が出来るのですが、例のごとくIEでつまずきます。
- IEでscriptタグの読み込み完了が捕捉出来ない
- 残念ながらIEはscriptタグのonloadが使えないのです
setIntervalやsetTimeoutを使う
同期的に読み込む試みは以前から行われていて、定期的に話題に上がっているのですが、 そこで行われているのが、setIntervalやsetTimeoutを使うという試みです。
簡単に説明すると、
- scriptタグの追加
- タイマーを使って、追加した外部JSの変数が定義されるかどうかを監視
- 変数が定義された事を確認した時に、次のscriptタグを追加する
- 上記を繰り返して、順番にscriptタグを追加していく
という処理を行い、scriptタグを順番に読み込む方法があります。
この方法には欠点があって
- 外部JSで定義される変数を知っておかないといけない
- そもそも変数を定義せず、処理だけを走らせる外部JSでは読み込みが完了したかどうか分からない
という問題があります。
そこで色々調べた結果、実装したのが次の方法です。
IEはonloadの代わりにonreadystatechangeを使う
タイマーを使う以外に方法はないかとMSDNを漁っていると、IEはonloadが使えない代わりにonreadystatechange が使える事が分かりました(ちなみにMSDN上ではonloadが使えるらしいのですが動作せず・・・)。
これを使えば、readyStateプロパティに読み込み状況が保存され、このプロパティが変わる度にonreadystatechangeのイベントが呼ばれます。 そしてこのイベント内で、readyStateが読み込み完了の時に任意の関数を呼び出すようにすると、コールバック関数が使えるようになります。
onloadと同等の事が出来るようになるので、後はコールバック関数を使って順番に外部JSを読み込む処理を書くだけです。
クロスブラウザな外部JSのロード関数はos0xさんの所で書いてくれています。
外部JavaScriptの動的ロード - 0x集積蔵
その他のアプローチも書いてあって参考になるので、ぜひ一読を。
蛇足ですが、読み込み完了時のreadyStateの値はキャッシュあり=comlete, キャッシュなし=loadedとなるようです。
外部スクリプトを読み込むJSLoder
onreadystatechangeを使って、scriptタグを同期(又は非同期)に読み込みつつ、間に処理を挟めるように作ったのが、JSLoderです。
サンプル
new JSLoder({
finish : function(){
console.log('全ての読み込み完了');
}
})
.next('first.js')
.next(function(){
console.log('firstの読み込み完了')
})
.next('second.js','third.js')
.next(function(){
console.log('secondとthirdの読み込み完了')
})
.start()
という感じでJSDeferdっぽく処理が出来るようになります。
これを使えば、ブログパーツ等も多少すっきりと書けます。(内部でdocument.write()等を使っていると、恐らく動きませんが)
詳細は以下から
おまけ
動的ローディングについてのリソース
- suVeneのあれ: [JavaScript]動的ロード(遅延ロード)3
- JavaScriptで外部ライブラリを読み込むためのスクリプトをCodeRepos.orgに上げた。 - holidays-l開発ブログ
- 動的スクリプトローディング(さんざん既出だと思うけど - IT戦記
- 岩家ぶろぐ ≫ [javascript] DQWindowManager - Dragon Quest のコマンドウィンドウのようなものを表示させる JavaScript
- 動的ローディング雑感 - IT戦記
- JavaScriptで外部ライブラリを読み込むためのスクリプトをCodeRepos.orgに上げた。 - holidays-l開発ブログ
- www.horaguchi.net - 外部JavaScriptの動的ロード
まとめると、IE--。
posted by 37to at : 20:01 | コメント (0) | トラックバック (0)
コメント
投稿する
トラックバック
トラックバックURI
一覧
この記事に対するトラックバックはまだありません。

この記事に対するコメントはまだありません。