JAVAスクリプトのdocument.write()メソッドでHTMLを書き出す場合、その書き出したHTMLに当てるスタイルには注意が必要です。
実際にどのような問題が起こるかを以下の実験で見てみましょう。
まず、以下のようなスタイルシートを用意します。
/* 通常の<em>要素は赤の太字で。 */em {font: normal bold 100% sans-serif;color: #f00;}/* <script>要素内の<em>要素は黒で。 */script em {color: #000;}/* <script>要素に続く<em>要素は青で。 */script+em {color: #00f;}
スタイルシートの内容はコメントにある通りですが、プロパティの継承と詳細度の関係から
それぞれ表示されるものとなります。
続いて、以下のようなHTML文書を用意し、先ほどのスタイルシートをリンクします。
<title>テスト</title><p><script type="text/javascript">document.write('<em>内部スクリプト</em>が書いたもの');</script></p><p><script type="text/javascript" src="TEST.js"></script></p>
要するに、
を見ている訳です。
最後に、このHTML文書と同じディレクトリに以下の内容のスクリプト TEST.js を用意します。
document.write('<em>外部スクリプト</em>が書いたもの');
要するに、先ほどのHTML文書に埋め込んでいるスクリプトと殆ど同じです。
では、このHTML文書を表示させると、どうなるでしょうか?
ファイヤーフォックスで表示させた場合、以下のようになります。
オペラ 9.0で表示させた場合、以下のようになります。
共に、<script>要素に続く<em>要素のスタイルである青文字で表示されました。
オペラでは<script>要素の直後に書き出したテキストが付け加えるようです。
尚、インターネットエクスプローラ 6.0は隣接セレクタを認識しないので、今回正しく考察出来ませんが、結果としては一般の<em>要素のスタイルである赤文字で表示されました。
ファイヤーフォックスとオペラの結果の違いを見るだけで、JAVAスクリプトがdocument.write()メソッドで書き出したHTMLが何処に書かれるのかは想定出来ない事が明らかとなります。
また、外部スクリプトの場合はファイヤーフォックスやオペラとも<script>要素の直後に書き出されるようですが、インターネットエクスプローラやサファリなどではどうなるかは判断出来ません。
さて、以上のようにJAVAスクリプトのdocument.write()メソッドで書き出すHTMLに対してスタイルを当てた場合、トラブルが起こり得る事が分かりました。
では、どのような場合にトラブルが起こるでしょうか。
思い付くものを挙げてみました。
例えば、あるブロックレヴェル要素の一番目の子要素に<script>要素を入れ、それが扱うスクリプトが書き出すHTMLに対して、first-child擬似クラスは適用されたり適用されなかったりとブラウザに依ってまちまちの結果となります。
HTMLの書き出しの際に当該<script>要素が書き出されたHTMLに置き換えられた場合には、そのHTMLが一番目に書き出す要素に対して、first-child擬似クラスは適用されるでしょう。
一方、当該<script>要素の直後に書き出したHTMLが続くようでしたらfirst-child擬似クラスが適用されるのは当該<script>要素となり、書き出したHTML内の要素には適用されないでしょう。
外部スクリプトからの書き出しの場合、多くは書き出したHTMLには当該<script>要素に後続する形になるため、script要素セレクタとの隣接セレクタで指定出来ます。
しかし、それも全てのブラウザで保障された挙動では無い事と、内部スクリプトからの書き出しではそうならない場合があるという問題があります。
いずれも、精密なスタイル作成には少なからぬ影響を与えるでしょう。
要するに、当該<script>要素がHTMLの書き出しに依って消えるかどうかに依って、
が決まるのですが、それがブラウザに依ってまちまちになっているのが問題なのです。
幾つかの方策がありますので、適切なものを撰びましょう。
例えば、隣接セレクタで セレクタA+セレクタB と言うセレクタを使う場合、セレクタBとなる要素がスクリプトによって書き出される場合には、
+セレクタB, セレクタA+script+セレクタBと言うように、script要素セレクタを間に挟んだ隣接セレクタも合わせて指定します。
また、first-child擬似クラスを用いる場合には、
:first-child, script:first-child+セレクタAと言うように、第一子要素がscript要素セレクタでそれに続く要素と言う隣接セレクタも合わせて指定します。
スタイルのためにクラス名を与えるのは好ましいとは言えませんが、どうしてもdocument.write()メソッドを使いたい場合にはやむをえないでしょう。
実はCSSとJAVAスクリプトの双方を巧く活用するには、DOMを利用するのが一番です。
DOMは文書のツリー構造を操作するため、ツリー構造を解析してスタイルを適用するCSSとの親和性も高いものとなっております。