Hatena::agenda経由で、ブラウザでミニマムXML (3):作るの記事を拝見したところ、ブラウザでDOM(document.implementation.createDocument
)により作成された新規の文書ノードについて、以下のような記述がありました。
新規の文書ノードはXML DOMの文書ノードと考えても(たいていは)大丈夫です。しかし、これはいいことばかりではありません。HTMLが持っていた豊富な機能性が使えないのです。例えば、getElementByIdメソッドは存在しないか、動かないか、動くかも知れないがお手軽にはいかないかです。
こういう状況が改善されるためには、XHTMLマークアップが一般化して、XML DOM(DOMコア)の拡張としてのHTML DOMが、ブラウザのdocumentとして実装される必要があります。いったい、いつになることやら。はたして、そのようになるかどうかもあやしいですしね。
この記述を読んで思ったのは、「文書要素の名前空間URIがXHTMLのものになっていれば、DOM HTMLも使えるものなのでは?」ということでした。以前にCSS切替スクリプトを作った時なんかでも、Firefoxではapplication/xhtml+xmlの文書でDOM HTMLのプロパティがふつうに使えていた覚えがあったので、新規に作成した文書でそうならないとは考えにくかったのです。
Firefoxでの実装を確認するため、以下のようなスクリプトを元にbookmarkletを作り、色々と書き換えて試してみました。
(function(){ var ns = 'http://www.w3.org/1999/xhtml'; var doc = document.implementation.createDocument(ns, 'html', null); var html = doc.documentElement; var body = doc.createElementNS(ns, 'body'); var p1 = doc.createElementNS(ns, 'p'); var p2 = doc.createElementNS(ns, 'p'); var p3 = doc.createElement('p'); html.appendChild(body); body.appendChild(p1); body.appendChild(p2); body.appendChild(p3); p1.appendChild(doc.createTextNode('foo')); p2.appendChild(doc.createTextNode('bar')); p3.appendChild(doc.createTextNode('baz')); p1.id = 'p1'; p1.title = 'title test'; p2.setAttribute('id', 'p2'); p2.className = 'hoge'; p3.setAttribute('id', 'p3'); alert(html.innerHTML /* ここで色々確認*/ ); })();
結果、文書要素の名前空間URIがXHTMLのものとなるように新規文書を作り、かつ文書内の要素もXHTMLの名前空間URIを持つように作れば、DOM HTMLで使える属性への簡易アクセスのためのプロパティ(id
, title
, className
等)やinnerHTML
、またid属性を目標にしたgetElementById
も問題なく使えるようでした。(確認はFirefox 1.0.7と1.5 Beta 2で行いました)
要素はcreateElementNS
で作らないといけない、というのが推測と違っていた点でした。createElement
で作った要素は、namespaceURI
の値がnullとなっており、DOM仕様で言うところのHTMLElement
とは見なされないようです。