window.open で生成した DOMWindowオブジェクトのDOCTYPEを指定する
完全に趣味の範囲ですが…。
下記コードで使われることになる document.implementation
ですが、主要ブラウザはほぼ対応しています。
ただしIE8のみDOMImplementation
は存在しているのに、メソッドがないという謎な状況になっています。
// wnd に DOMWindowを入れる。 var wnd = window.open("about:blank", "_blank"); // DocumentTypeオブジェクトを作る。 var doctype = document.implementation.createDocumentType( "html", "-//W3C//DTD XHTML 1.0//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); // 挿入します。 wnd.document.insertBefore(doctype, wnd.document.getElementsByTagName("html")[0]); // IE9はここで例外
IE9ではDocumentTypeオブジェクト挿入の段階で DOM Exception: HIERARCHY_REQUEST_ERR (3)
な例外が発生します。
回避方法が分かりません…。
Rangeオブジェクトで範囲とってぶち込めばいいのかな?
回避方法が分かりました。
DocumentTypeを作るのはwnd内でやらなきゃいけなかったみたいです。
なんでこんな初歩的なことに気付かなかったんだ…。
var doctype = wnd.document.implementation.createDocumentType( "html", "-//W3C//DTD XHTML 1.0//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); wnd.document.insertBefore(doctype, wnd.document.getElementsByTagName("html")[0]);
挿入時のコードですが、たぶん
wnd.document.insertBefore(doctype, wnd.document.firstChild);
でもいいような気がします。
また、RangeオブジェクトでinsertNode
するのもアリです。
var range = document.createRange(); range.selectNodeContents(wnd.document); // もしくは range.selectNode(wnd.document.getElementsByTagName("html")[0]); range.insertNode(doctype);
こっちの方がよりDOMを触ってる感じがしますね!
ただし、IE8以下ではRangeオブジェクトは使えません。
あと、今回は挿入に insertBefore
を使っていますが、
これではなく appendChild
を使うと、HTML上では
<html> <head></head> <body></body> </html> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
という許されざる状況になるのでよくないと思います。
最後に、createDocumentType
メソッドの第二引数と第三引数に null
を渡してあげると、HTML5形式になります。