DOM
クライアントサイドの JavaScript は主に、HTML 文書を動的に操作することによって、ウェブアプリケーションを開発するために使われます。
JavaScript から HTML 文書を操作するにはどうしたらよいでしょうか。
ここでは HTML 文書を操作するためのインターフェイスである DOM について説明します。
W3C DOM とは?
JavaScript は Netscape ウェブブラウザに実装されて普及したという経緯から、ウェブアプリケーションの構築に使われます。
アプリケーションを構成するためには、特定の場所からのデータを読み取る、特定の HTML 要素の内容を必要に応じて別の内容に差し替える、 あるいは属性を変更するなどといった操作が必要となります。
JavaScript が HTML 文書にアクセスして、その内容を差し替える、変更するなどするために、DOM "Document Object Model" という API が作られました。
古くは Netscape、IE4 などがそれぞれ DOM を開発しました。しかしブラウザ毎に動作の異なる API では非常に不便なので、W3C が標準化を進めました。 その結果定義されたのが W3C DOM スタンダードです。
DOM Level 1 (1998年)、DOM Level 2 (2000年)、そして DOM Level 3 (2004年) とそれぞれ定義され、現行の主要ブラウザも、 新しい DOM 標準をサポートしようと努力しています。
どのブラウザがどの程度のサポートをしているか、ということについてはそれぞれのブラウザのドキュメントをみてください。
当サイトでは全てを網羅することはできませんので、W3C DOM の基本的な考え方、便利でよく使う機能について説明します。
DOM を構成する要素
DOM では HTML 文書をツリー構造で表現します。ツリーはノード (Node) で構成されます。
DOM Level 1 では Node インターフェイスは次のように定義されています。
interface Node { // NodeType const unsigned short ELEMENT_NODE = 1; const unsigned short ATTRIBUTE_NODE = 2; const unsigned short TEXT_NODE = 3; const unsigned short CDATA_SECTION_NODE = 4; const unsigned short ENTITY_REFERENCE_NODE = 5; const unsigned short ENTITY_NODE = 6; const unsigned short PROCESSING_INSTRUCTION_NODE = 7; const unsigned short COMMENT_NODE = 8; const unsigned short DOCUMENT_NODE = 9; const unsigned short DOCUMENT_TYPE_NODE = 10; const unsigned short DOCUMENT_FRAGMENT_NODE = 11; const unsigned short NOTATION_NODE = 12; readonly attribute DOMString nodeName; attribute DOMString nodeValue; // raises(DOMException) on setting // raises(DOMException) on retrieval readonly attribute unsigned short nodeType; readonly attribute Node parentNode; readonly attribute NodeList childNodes; readonly attribute Node firstChild; readonly attribute Node lastChild; readonly attribute Node previousSibling; readonly attribute Node nextSibling; readonly attribute NamedNodeMap attributes; readonly attribute Document ownerDocument; Node insertBefore(in Node newChild, in Node refChild) raises(DOMException); Node replaceChild(in Node newChild, in Node oldChild) raises(DOMException); Node removeChild(in Node oldChild) raises(DOMException); Node appendChild(in Node newChild) raises(DOMException); boolean hasChildNodes(); Node cloneNode(in boolean deep); };
Node では親ノード、子ノードをたどるための parentNode、childNodes プロパティがそれぞれ定義されています。 また同世代のノードをたどる previousSibling、nextSibling もあります。
これらによって HTML ドキュメントを表すツリー内をたどることが可能です。
HTMLDocument も Node
そして Document インターフェイスも、Node を継承して次のようになってます。
interface Document : Node { readonly attribute DocumentType doctype; readonly attribute DOMImplementation implementation; readonly attribute Element documentElement; Element createElement(in DOMString tagName) raises(DOMException); DocumentFragment createDocumentFragment(); Text createTextNode(in DOMString data); Comment createComment(in DOMString data); CDATASection createCDATASection(in DOMString data) raises(DOMException); ProcessingInstruction createProcessingInstruction( in DOMString target, in DOMString data) raises(DOMException); Attr createAttribute(in DOMString name) raises(DOMException); EntityReference createEntityReference(in DOMString name) raises(DOMException); NodeList getElementsByTagName(in DOMString tagname); };
さらに HTMLDocument は Document を基にして・・・
interface HTMLDocument : Document { attribute DOMString title; readonly attribute DOMString referrer; readonly attribute DOMString domain; readonly attribute DOMString URL; attribute HTMLElement body; readonly attribute HTMLCollection images; readonly attribute HTMLCollection applets; readonly attribute HTMLCollection links; readonly attribute HTMLCollection forms; readonly attribute HTMLCollection anchors; attribute DOMString cookie; void open(); void close(); void write(in DOMString text); void writeln(in DOMString text); Element getElementById(in DOMString elementId); NodeList getElementsByName(in DOMString elementName); };
つまり HTMLDocument も Node ということになります (is-a の関係) 。
HTMLDocument は Window.document から取得可能
HTMLDocument は クライアントサイド JavaScript のグローバルオブジェクトである Window オブジェクト の、 document プロパティで取得できます。
例えば、次のようにすると・・・
document.write( document.title );
このページでは次の結果を得ます。
上記の HTMLDocument の定義には、確かに title プロパティも、write メソッドも用意されていますね。