html要素へのアクセス(1)-DOMによるアクセス
この記事では基本的には IE でも Firefox でも動作する DOM の API を扱っている。
jQuery (のセレクタ)などの Ajax ライブラリを使えばもっと簡単に JavaScript から複雑な html 要素へアクセスする事ができるが、DOMのAPIについても基本的な事を知っているとそれなりに役に立つと思う。
getElementXXXメソッドによる特定のhtml要素へのアクセス。
- document.getElementById
指定されたIdの要素ノードを取得する。 - document.getElementsByName(引数)
name属性が引数と同じである要素ノードのリストを返す。
name属性が指定可能なタグは以下のものに限られるらしい。
aapplet,button,form,frame,iframe,img,input,map,meta,object, param,select,textarea
またxhtmlではaタグとmapタグでも使えないようだ。 - document.getElementsByTagName(引数)
引数で指定されたタグ名と一致するすべての要素ノードのリストを返す。 - 要素ノード.getElementsByClassName(引数)
引数で指定されたクラス名と一致するすべての要素ノードのリストを返す。
HTML5 でも定義されているがIEや古いブラウザでは使えないらしい。
getElementById以外のElementsと複数形になっているメソッドは複数の要素を返すので個々の要素に対しては 配列のようにアクセスする。
getElementsByTagNameとgetElementsByClassNameはdocumentオブジェクトだけでなく要素ノードに対しても使えるらしい。
サンプル1-getElementXXXメソッドによる特定のhtml要素へのアクセスの例
ノードのリストの各要素にアクセスするにはitemメソッドを使う事もできる。
サンプル2-サンプル1をitemメソッドを使って書き換えた例
ノードの情報
-
ノード.nodeName
tagNameを参照。 -
ノード.nodeType
要素ノード(Elementインタフェイス) :1
属性ノード(Attrインタフェイス):2
テキストノード(Textインタフェイス):3
-
ノード.nodeValue
- 要素ノード:null
子要素のテキストを返すと勘違いしやすいが - 属性ノード:属性値
- テキストノード:テキストの値
- 要素ノード:null
-
ノード.tagName
HTMLの場合は大文字,XHTMLの場合は小文字でタグ名を返す。
nodeName は tagName と同じ値になる。
tagName が未定義 の場合、 通常はテキストノード - ノード.name
nodeNameと混同しやすいが単なるタグのname属性の値
-
要素ノード.innerHTML
要素ノードのタグ内のHTMLテキストを返す。
子ノードへのアクセス
-
要素ノード.childNodes
要素ノードのすべての子ノードのリスト(NodeList)を返す。
NodeListのlengthプロパティは子要素の数を返す。 -
要素ノード.firstChild
要素ノードの最初の子ノードを返す。 -
要素ノード.lastChild
要素ノードの最後の子ノードを返す。 -
要素ノード.hasChildNodes()
子要素が存在するかどうかを示す。
childNodesの何個目の要素がどの項目に該当するかはIEとFireFoxとでは異なる。
これは、いわゆる「ホワイトスペースノード」(改行,スペース,タブ)をIEでは子ノードとみなさないのに対して、 FireFoxでは子ノードとして認識するためである。
サンプル4では、tagNameがあるかどうかを判断してテキストノードをスキップして、 ホワイトスペースノードを項目として取得しないようにしている。
DOMツリーの状態を、FireFoxとIE(IE8)で確認する事ができる。
FireFoxの場合は、メニューの「ツール(T)」→「DOM Inspector(N)」を選択する。
IE8の場合は、メニューの「ツール(T)」→「開発ツール(L)」を選択する。
FireFoxの場合には、DOMツリーに以下のように「#text」と「ホワイトスペースノード」が余分に表示されているのが確認できる。
親ノードへのアクセス
-
要素ノード.parentNode
要素ノードの親ノードを返す。
兄弟ノードへのアクセス
-
要素ノード.previousSibling
要素ノードの1つ前の要素ノードを返す。
1つ前の要素ノードが存在しない場合はnullを返す。 -
要素ノード.nextSibling
要素ノードの1つ後の要素ノードを返す。
1つ後の要素ノードが存在しない場合はnullを返す。
サンプル5では、idがfooのhtml要素から後の項目result1と、前の項目result2を、取得して表示している。
ノードの操作
ノード作成
-
document.createElement(引数)
引数で指定されたタグの要素ノードを作成する。 -
document.createTextNode(引数)
引数で指定された文字列のテキストノードを作成する。
ノードのコピー
-
ノード.cloneNode(引数)
ノードのコピーを返す。
引数がtrueの場合はそのノードのすべての子ノード,子孫ノードを含めてコピーする。
引数がfalseの場合は子ノード以下をてコピーしない。
ノードの挿入
-
要素ノード.appendChild(引数)
子ノードの最後に、引数で指定したノードを追加する。 -
要素ノード.insertBefore(引数1,引数2)
ノードの子ノードとして、引数2で指定した要素ノードの前に、引数1のノードを挿入する。
insertAfterというメソッドがあっても良さそうだが、そんなメソッドは存在しない
引数2がnullの場合は、要素ノードの子ノードの最後に追加する。
この事を利用して下のサンプル6のように、insertBeforeメソッドを使ってinsertAfterの機能を実現できる。
サンプル6-createElement,createTextNode,cloneNode,appendChild,insertBeforeそしてparentNodeの例
まとめて一度に複数のノードを挿入する時の効率アップ
- document.createDocumentFragment()
DocumentFragmentオブジェクトを取得する。
一度に複数のノードを追加する場合には、一旦、 追加したいノードをcreateDocumentFragmentメソッドで取得した DocumentFragmentオブジェクトに対して、追加したいノードを追加して、 最後にこのDocumentFragmentオブジェクトを目的のノードに追加した方が処理効率が良いそうだ。
※.蛇足ではあるが、DocumentFragmentは Java言語のStringクラスに対する StringBufferクラスのようなもの、と考えるとわかりやすいかも?
サンプル7-サンプル6のコードをcreateDocumentFragmentを使って書き換えた例
ノードの削除
-
要素ノード.removeChild(引数)
引数で指定された子ノードを削除する。
ノードの置換
- 要素ノード.replaceChild(引数1,引数2)
引数2で指定された子ノードを引数1で指定されたノードに置き換える。
要素ノードの属性の操作
属性値の取得
- 要素ノード.getAttribute(属性名)
要素ノードの属性値を返す。
属性値の設定
- 要素ノード.setAttribute(属性名,属性値)
指定の要素ノードの属性名で示される属性の値を設定する。
属性が存在しない場合は追加する。
属性の存在の確認
- 要素ノード.hasAttribute(属性名)
要素ノードに指定された属性名が存在するかどうかを論理値で返す。
属性の削除
- 要素ノード.removeAttribute(属性名)
要素ノードの指定された属性名の属性ノードを削除する。
属性ノードの操作
まぎらわしいが、属性の値ではなく属性ノードを操作するメソッドとして以下のものがある。- document.createAttribute(属性名)
指定された属性名の属性ノードを作成する。
- 要素ノード.getAttributeNode(属性名)
指定された属性名の属性ノードを取得する。
- 要素ノード.setAttributeNode(属性ノード)
指定された属性名の属性ノードを変更する。
属性ノードが存在しない場合は追加する。 - 要素ノード.removeAttributeNode(属性ノード)
指定された属性名の属性ノードを変更する。
属性ノードが存在しない場合は追加する。 - 要素ノード.attributes()
要素ノードのすべての属性ノードのリストを取得する。
取得したノードリストのlengthプロパティにより、要素の属性ノードの数を知る事ができる。
参考URL