JavaScriptのdocument.writeとsetTimeoutの併用はページを非表示にする

特定のページがなぜか非表示になる

5月某日、某Webサイトの特定のページがなぜか非表示になるので原因を調べてほしいという依頼があった。

Webサイトを見たところ、特定のページだけが表示されたあと数秒後に非表示になった。(真っ白)

Webサイトで一度表示されたあと何も表示されなくなるのはリダイレクトで何もないページにリダイレクトされているか、JavaScriptで消されているかのどちらかの可能性が高い。

今回はURLがリダイレクトにより変わっていなかったので原因はJavaScriptということになる。そしてコード内をsetTimeoutで検索したところ該当するコードを見つけた。

document.writeとsetTimeoutでページが消える

document.writeは文字列の書き出しに使用され、タグを書き出すこともできる。そのため、昔はdocument.writeでタグを追加するコードが結構あった。

<h1>foo</h1>
<script>
document.write('<h2>bar</h2>');
</script>

document.writeでタグを追加したサンプル

現在はdocument.writeを使用すると様々な問題が発生するため使用されることはほとんどない。

例えばdocument.writeとsetTimeoutを併用するとbodyタグ内がdocument.writeの内容にすべて上書きされるという問題がある。

document.writeとsetTimeoutでタグを追加したサンプル

document.writeは非推奨

そもそもdocument.writeを使用すると上記以外にも様々な問題を引き起こすため、現在document.writeの使用は非推奨になっている。

もしも自身が管理しているWebサイトでdocument.writeが含まれるコードがあったら書き換えたほうが良いだろう。

document.write使用時に発生する問題一覧

  • document.writeとsetTimeoutでページが消える
  • XHTML文書で動作しない
  • deferredまたはasynchronousのスクリプト内で無視される
  • Microsoft Edgeのときiframe内で複数回使用するとエラーになる
  • 低速のネット回線だと実行されないことがある
  • ブラウザによって挙動が異なる

scriptタグ追加で真っ白になる

document.writeとsetTimeoutを併用してscriptタグを追加した場合はページが真っ白になってしまう。

古いサイトや古いサイトのコードを継承しているページだと前述のコードによりページが真っ白になって消えてしまっていることがある。

私が調べた限りではdocument.writeとsetTimeoutを併用しているWebサイトは現在でもそれなりに存在する。

例えば明石観光協会のWebサイトなどはdocument.writeとsetTimeoutを併用してscriptタグを追加しているため、一度ページを表示したあと、5秒後に消えている。(現在は指摘によりコメントアウト)

setTimeout(function(){
(function(d){
if(typeof(window.NINJA_CO_JP_ONETAG_BUTTON_a3fd60f3141fd990f883728062f70dba)=='undefined'){
    document.write("<sc"+"ript type='text\/javascript' src='\/\/omt.shinobi.jp\/b\/a3fd60f3141fd990f883728062f70dba'><\/sc"+"ript>");
}else{
    window.NINJA_CO_JP_ONETAG_BUTTON_a3fd60f3141fd990f883728062f70dba.ONETAGButton_Load();}
})(document);
},5000);

document.writeとsetTimeoutを併用している関係上、一見正しく表示されていても数秒後に消えてしまうと発見しにくい。

全文検索でdocument.writeが書かれているコードがないか探して、該当箇所はappendChildなどの記述に書き換えたほうが良いだろう。