読み込みのタイミングによっては外部 script のdocument.writeは無視される

外部サイトの事情やら歴史的経緯やらで、document.writeを直接行なうような、JavaScriptを<script src >を使って動的に読み込まなくてはいけないことがあります。この時、誤ってscript要素をappendChildしたりして非同期に読み込みすると、スクリプト内のdocument.writeが無視されることがあります。

例えば以下の例のように、script要素をつくってappendChildすると、外部scriptは非同期に実行されます。この実行タイミングによっては、document.writeを実行しても何も起こらないように見えます。

https://gist.github.com/hakobe/5243675

これは、"HTML 構文解析器が HTML 文書の末尾まで来たタイミングより後で <script src> で指定されたスクリプト経由で実行されると、document.write は黙って無視される" *1という仕様によるものです 。

仕様については、 http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter 周辺をご確認ください。id:nobuoka さんの 外部 script の document.write が何もしない条件などについて - ひだまりソケットは壊れない の解説が詳しい!

HTML 構文解析器が HTML 文書の末尾まで来て document.writeの書き込み先がなくなってしまったあとで、document.writeすると、documentを再openして画面全体を書き換えてしまいます。いかにもdocument.write要因ぽい症状なのですぐに原因はわかりますが、<script src>経由で同様のことをしてしまうと、エラーも何もでないので、原因を理解しづらい感じですね。

*1:wakabatan に教えてもらいました!