HTML5でdocument.writeは使ってはいけない?
document.writeはJavaScriptを書く方でしたらおなじみですね。JavaScriptを学び始めた頃にdocument.write(Hello world);なんて書いた人も多いのではないでしょうか。ところがなんと「HTML5ではdocument.writeを使ってはいけないらしい」という話を耳にし、真相を確かめるべく調べてみました。
仕様書から読み解くdocument.write
こーゆー時はまずHTML5の仕様書です。早速W3Cのサイトを見に行くと丁度2011年4月6日にHTML5関連のドキュメントがアップデートされていました。
HTMLの仕様書の中の3.5 Dynamic markup insertionにdocument.writeの記述があります。
そこを見ると「Warning!」と書いてあって赤字で以下のような記載がありました。
This method has very idiosyncratic behavior. In some cases, this method can affect the state of theHTML parser while the parser is running, resulting in a DOM that does not correspond to the source of the document. In other cases, the call can clear the current page first, as if document.open() had been called. In yet more cases, the method is simply ignored, or throws an exception. To make matters worse, the exact behavior of this method can in some cases be dependent on network latency, which can lead to failures that are very hard to debug. For all these reasons, use of this method is strongly discouraged.
要約(意訳)すると「パースして生成されるDOMに影響与えてしまったり、ネットワークの遅延にメソッドの動作が影響されデバッグが困難になったりといった問題があるのでdiscouraged(推奨されない)」と書いてあります。しかもstronglyとまで。W3Cとしてもdocument.writeはかなり厄介者扱いですね。その証拠に上記の一番最初にはThis method has very idiosyncratic behavior.
と書いてありますから、W3Cのワーキンググループでもdocument.writeは悩みの種となったのでしょう。
仕様書にstrongly discouragedと書いてありますので、やはりHTML5でdocument.writeを使うのは避けた方が良さそうです。
ふと「以前から仕様書に推奨しないと書いてあったっけ?」と思い、これまでの仕様書も洗ってみました。その結果、はっきりとdocument.writeについてstrongry discouragedと書いてあるのは2010年10月19日の仕様書からでした。
document.writeの代替え方法はないの?
HTML5でdocument.writeは使わない方が良いのであれば、問題はその代替の方法です。これについてはPolyglot Markup: HTML-Compatible XHTML Documentsに記載がありました。(ちなみにこのPolyglot MarkupのドキュメントはHTML5をXHTMLにも適合させて書くためのHow toが書かれています。まだ読んでいない方はご一読することをおすすめします)
9. Script and Styleに以下のような記載があります。
Instead, use the innerHTML property for both HTML and XHTML.
「(document.writeの)代わりにinnnerHTMLがHTMLとXHTML両方で使えるよ〜(意訳)」とありますので、innerHTMLを使えば良いということみたいですね。
HTML形式なら使ってもOKなのか?
しかし「both HTML and XHTML」って記述が気になりますね。ということで、その部分をもう少し見てみますと次のような記載がありました。
Although document.write() and document.writeln() are valid in an HTML document, neither function may be used in XHTML. Therefore, neither is used in polyglot markup.
この文章から読み取れるのは「document.writeはHTMLではvalidだが、XHTMLではinvalid」ということですね。そしてpolyglot markup(HTML5をXHTML形式にも適合させたマークアップ)を行うのであればdocument.writeは使えないということです。逆に言えばHTML5をXHTMLに対応させない場合は「まぁ使ってもOKだよ」ってスタンスなんでしょうかね?このへんは議論の余地がありそうです。
仕様書から読み解くW3Cの本音
さらのその下に次のような一文が
XML parsers parse the string as XML in XHTML. HTML parsers parse the string as HTML in HTML. Because of the difference in parsing, if you send the parser content that does not follow the rules for polyglot markup the results will differ for a DOM create with an XML parser and one created with an HTML parser.
(意訳)「XHTMLはXMLパーサーがXMLとして処理を行い、HTMLはHTMLパーサーがHTMLとして処理をする。これらのパースの違いによりpolyglot markupのルールに沿っていないコンテンツはXMLパーサーとHTMLパーサーによって処理されたものでDOMが異なります。(意訳)」
つまり、document.writeを使うとpolyglot markupのルールに沿っていないのでXMLパーサーとHTMLパーサーでDOMが異なってしまうということになります。HTML5でdocument.writeを使うリスクはこのあたりにありそうです。W3CとしてはXHTMLに沿ったHTML5(XMLとしてパースできるHTML5)を広めたいのでしょう。その意味でもdocument.writeは極力仕様をやめてもらいたいというのがW3Cの本音なのではないでしょうか。
まとめ
- HTML5ではdocument.writeは使わない方が良い(2011年4月6日時点の仕様書に依る)
- XHTMLに適合させないHTML5ではdocument.writeを使っても文法的にはvalidである。(しかしXHTMLとしてのメリットは失われる)
HTML5はまだ草案の段階ですので今後仕様が変更される可能性があります。