document.writeがイベントタイミングによって挙動が違う

document.writeがイベントタイミングによって挙動が違う

JavaScriptをここ数年扱ってきているが、最近の流行言語で第2位まで上昇していたんですね。※

アメーバニュース

確かに採用面談していても、フロントエンジニアという言葉を、すごくよく聞くようになったし、希望する人も増えているようだ。

個人的には、デザイナーが、WEBページを動的にしたい為にjQueryを使うっていう人が多いように思えます。

JavaScriptは簡単か?

プログラマーにとって、コンパイル不要、ソース実行可能なインタプリタ言語は全般的に簡単な部類だと考えられています。しかし、環境構築の容易性、開発工程の短縮、ブラックボックス度合い、などから「簡単」と言っているだけで、

いざ製品開発に関わるとなると、実際は、非常に複雑な言語だと思ってます。

その中でも、「document.write」という仕様は、非常に便利なのですが、ともすると、予期せぬ障害を引き起こす危険のある命令であり、その挙動に複数の結果があるので注意事項としてメモしておきます。

簡単に説明

HTMLソース内の</html>の下(ソースの一番下)に以下を書いてみましょう。

通常の書き方

//* 実行結果
// 〜画面表示〜
// hoge!

ページの一番下に「hoge!」が表示されたと思います。

次にこれを、以下の様な書き方で行うとどうなるか・・・

onloadイベント後

//* 実行結果
// 〜画面真っ白〜
// hoge!

なんという事でしょう!
ページが真っ白になって、「hoge!」の文字だけに・・・

document.writeは、HTMLソース上に、タグや文字列を追加する時に利用するものなのですが、通常で書くと、上のような書き方で、さほど問題は置きないんですが、
Ajax対応などで、「ページの読み込み後に文字を挿入・・・」みたいな事で下のような書き方をすると、画面がぶっ飛んでしまいます。

無名関数で書いてみましょう

// *実行結果
// 〜画面表示〜
// hoge!

これは正常に表示されました。

setTimeoutではどうでしょう?

// *実行結果
// 〜画面真っ白〜
// hoge!

画面が表示されてから、5秒後に、またもやホワイトアウト!!

検証結果

どうやら、settimeoutは、ページロード後に行われているので、どうやら、ページがonloadを境に、document.writeの挙動が変わっているのではないかと推測。

対応策

この結果を元に、商品設計をする際は、

・onload前では、document.writeを使ってOK
・onload後では、document.writeの使用がNG

と考え、以下の様なプログラムが最適と考えました。

# 外部JSをファイル”hoge.js”

# HTMLソース記述

→実行結果
<head>タグ内に記述 → 問題なし

<body>タグ内に記述 → 問題なし

イベントに記述 → 問題なし

全てのタイミングで問題なく実行されることが確認できました。

結論

loadイベントの判定でreadyStateを使うと、ブラウザ毎に返ってくる値が違う場合があるので、色々と調べたところ、onload後に「complete」という値は、あのエンジニアを悩ませ続けたIE6でも問題なく返って来た値なので、会社のサービスとしては、これで安定するというお墨付きができました。

この危険な「document.write」という関数は、使わない方がいいように思うかもしれませんが、onload前であれば、実はこの機能でしか実装できない事もあるため、避けては通れない機能でもあり、こういったDOM構造の動的対応という事を把握しておかなければ、他の命令でも、痛い目を見るという事も同時に提唱したいと思います。

さて次は、「setInterval」でも調べますか・・・

コメント