DOMはHTMLとほとんど同型のツリー構造をとるが、HTMLにおける要素ノード以外にも、いくつか種類がある。下記にDOMノードの種類を示す。
要素ノード
HTMLの要素に対応するノード。複数の属性を持ち、さらに子ノードを持つ。
具体的にはelement.getElementsByTagName()やdocument.getElementById()で取得できる。
ルートノード
HTMLではhtml要素が全ての要素のルートとなっているが、DOMではさらに上位にdocumentというルートノードが存在する。
テキストノード
文字列を格納するノード。子ノードを持たない。
上記のノードを取得・変更・追加・削除するためのAPIの規定がDOMである。
次にDOMを操作・取得するための関数を下記に示す。
DOMの関数
指定したid属性の値を持つ要素ノードを取得するメソッド
document.getElementById(id)
呼び出し元のノードの子孫要素の中で、指定した要素の名前を持つ要素ノードをリストとして取得するメソッド
element.getElementsByTagName(name)
呼び出し元のノードの子孫ノードの中から、指定したクラス属性の値を持つ要素ノードをリストとして取得するメソッド
element.getElementsByClassName(name)
呼び出し元のノードの指定した属性の値を取得するメソッド(ただし、ほとんどの属性には同名のプロパティが用意されている)
element.getAttribute(name)
呼び出し元のノードの直下のすべてのノード(テキストノード含む)のリストを取得するプロパティ
element.childNodes
呼び出し元のノードの直下の最初のノードを取得するプロパティ(element.childNodes[0]と同じ)
※ちなみにelement.firstElementChildとすると、最初の要素ノードの取得になる
element.firstChild
(例)子要素すべてを削除
let $el = document.getElementById('hoge'); while ( $el.firstChild ) { $el.removeChild($el); }
指定した要素名の要素ノードを生成(生成後はappendChild()やinsertBefore()を使って、任意の場所に挿入)
document.createElement(name)
指定した文字を格納したテキストノードを生成(生成後はappendChild()やinsertBefore()を使って、任意の場所に挿入)
document.createTextNode(text)
呼び出し元のノードの子ノードの一番最後に指定したノードを追加
element.appendChild(node)
呼び出し元のノードの指定した子ノードを削除
element.removeChild(node)
指定したノードの直前にノードを挿入
insertBefore(node, ref)
より簡単にノードを取得できるAPIとしてSelectors APIがある。
今はこちらの方が主流。
上記の「element.getElementsByClassName(name)」「element.getElementsByTagName(name)」また「document.forms」などのDOM APIとSelectors APIの大きな違いとしては、上記の場合はLive NodeList(単純にNodeListと呼ばれることもある)を取得するのに対してSelectors APIはStatic NodeList(HTMLCollectionと呼ばれることもある)を取得する。
両者の違いは、別の概念で言い換えると、要素のコピーを取得するかポインタを取得するかの違いだと筆者は思っている。
それぞれ使用できるメソッドの違いがもちろんあり、混合することでよく発生するエラーは、下記のような感じ。
Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
Selectors APIはjQueryライクにかけるので、まだjQuery使っている人でも簡単に導入できると思う。
Selectors API
呼び出し元のノードの子ノードの中から、指定したセレクタで一番最初の要素ノードを取得
document.querySelector(selector)
呼び出し元のノードの子ノードの中から、指定したセレクタのすべての要素ノードを取得
document.querySelectorAll(selector)