外部スクリプトを動的読込して同期的に処理をする方法
背景
document.write
を使ってる外部ライブラリを動的読込する必要があった- そのライブラリが読み込まれた後にしなければならない処理がある
document.write
は使うなってあれほど言ってるのに!!
それでもそんなライブラリ(内製だった…)を使わなければならない場面もあります。しかも<script src="..."></script>
で読み込めず、動的読込(※)しなきゃいけない場面もあります。それが人生です。
※動的読込の例
<script>
if (conditions) {
var scriptElement = document.createElement('script');
scriptElement.src = '//cdn.hoge.com/library.js';
var headElement = document.getElementsByTagName('head')[0];
headElement.appendChild(scriptElement)
}
</script>
でもdocument.write
が使われているライブラリは動的読込しようとしても読み込めません!💢💢
HTML解析が始まりDOM操作によって追加された外部スクリプトのdocument.write
は無視されます。そのせいで普通に動的読込しても何も起こらないのでした😉
結論
- iframeで動的読込する
- iframe.onloadを使って後続処理をする
解説
1. create iframe to load a library
document.write
を含むライブラリを読み込むための、iframeを準備します。
iframeを使うことで擬似的に別のHTMLをつくり、そいつにライブラリを読み込んでもらう算段です。iframeは今この場で生成しているのでHTML解析がまだ始まっていないから、document.write
のあるライブラリも読み込めます。
ちなみにここではiframeを用意しただけで中身(ライブラリを読み込むためのscriptタグ)はまだ書いていません。
2. some functions after loading a library
ライブラリ読込後の後続処理はonload
を使います。onload
イベントはsrc属性により指定されたリソースの読み込み完了時に発生します。ありがたや。
3. write sctipt tag in iframe
iframeにscriptタグを書き込みます。document.write
にはちょっとひとクセあって、文書ストリームを勝手に開いて文字列を書き込むんですね。そして開いたら開きっぱなし(これが使うなと言われる所以)。なので明示的にopen
, close
をします。
(closeだけすりゃいいんだけども。見栄え的にopenもしてみた)
参考
こんな感じに少々ゴリ押し技を組み合わせて実現しました。今回は一時凌ぎの実装だったのでこのような手段を取りましたが、あまりおすすめできる技ではありませんのでご利用は程々に。