9章 DOM
DOMとは
DOM Level1
- p246 Coreモジュール…HTMLに限らない一般的なDOM操作についての仕様
- HTMLモジュール…HTML文章向けのメソッド
- p247 getElementsByTagName…タグ名を指定して要素を取り出す
- createElement…要素を作成
- appendChild…要素を挿入
DOM Level2
- IE8以下はDOM Level2に準拠せず
- Core、HTMLモジュール…Level1の拡張
- Views…文章の表示関連の仕様
- Events…イベント関連
- Style…スタイルシート関連
- Traversal and Range…DOMツリーをたどる方法や範囲指定関連
DOM Level3
DOM Level0
- p248 DOMが規定される前にブラウザが実装していたもの
- Window,Document,Navigator,Location,Historyなどが互換性のために残されている
- DOM Level1で定義されたり、HTML5に組み込まれた
- 名前の衝突を避けるため、Firefoxならmoz、Google ChromeとSafariはwebkitというプレフィックスをつける
DOMの記述
DOMの基礎
タグ、要素、ノード
- タグとは、マークアップとして記述される文字列
- p249 開始タグと終了タグがある
- 要素、ノードは、継承関係にあり、ノードがスーパータイプ
- ノードにはnodeTypeという属性があり、ELEMENT_NODE(ノードタイプの値が1)のものが要素になる
- 要素はElement
- 属性ノード(Attr),テキストノード(Text),コメントノード(Comment),文章ノード(Document)
DOM操作
- JavaScriptの役割は、Webページのタグ、要素、ノードを操作してインタラクティブ性を提供すること
- 選択、作成、変更、削除
Documentオブジェクト
- DOMツリー構造のルートノード
- 対応するHTMLタグはない。htmlタグやbodyタグは、DocumentオブジェクトのdocumentElementプロパティとbodyプロパティに対応
- JavaScript内からdocumentでアクセスできる。windowのプロパティであり、windowはグローバルオブジェクトなので、windowは省略できる
- windowオブジェクトはDOMツリー構造に含まれない
ノードの選択
IDによる検索
- p250 document.getElementById(ID名)
- IDはDOMツリーの中で一意にする。一意になっていない場合の挙動は規定されていない
タグ名による検索
- p251 document.getElementsByTagName(タグ名)
- タグ名に'*'を指定するとすべての要素を取得
- Elementオブジェクトで量すると、そのElementオブジェクトの子孫ノードの中から見つける
- ライブオブジェクトの特徴
- getElementsByTagName()の結果は、NodeListオブジェクトで、配列ではないことに注意
- NodeListオブジェクトはライブオブジェクトである
- ライブオブジェクトとは、取得したタイミングの状況ではなく、常に現状に応じた変化を得られるオブジェクトである
- p252 ライブオブジェクトを操作する上での注意点
- ライブオブジェクトの要素数をループに使い、ループ内で要素を追加すると無限ループになるので注意
- p253 ライブオブジェクトのパフォーマンス
- パフォーマンス面では不利な実装
- そのまま利用するより、一度Arrayに変換した方が速い
- Array.prototype.slice()を使って、NodeListオブジェクトに対して適用する
var array = Array.prototype.slice.call(nodelist);
-
- 以上で、nodelistをthisとしてsliceを実行すると、区切り文字がないのでそのまま配列として得られる
- この方法はIE8以前には利用できない
- IE8用のコーディング例
- p254 NodeListの操作によるパフォーマンスの違い
- 書籍の例では10倍ほど違う。書籍は2011年当時のものなので、最新でも試しておくとよい
- p255 HTMLCollectionもライブオブジェクト。DOMLevel1で規定されているHTMLCollection一覧
- ライブラリでArrayに変換するものもある。パフォーマンスが影響する部分は確かめるとよい
名前による検索
- p256 HTMLDocument.getElementsByName(名前)で、name属性の値で取得可能
- nameはformタグやinputタグで利用
- それ以外は通常はid
クラス名による検索
- HTMLElement.getElementsByClassName(クラス名)
- 複数のクラス名を検索する場合は空白区切りで指定し、両方のクラスが指定されているものを抽出
- HTML5で実装
- IE8以前では使用できないが、汎用JavaScriptライブラリの多くで実装されているので、それを利用すると同等のことが可能
親、子、兄弟
ノードの作成・追加
- ノードの作成には、Document.createElement()、Document.createTextNode()、Document.createComment()を使う
- 作成したノードを、Node.appendChild()や、Node.insertBefore()で、HTMLドキュメントに追加
ノードの内容変更
- 取得したNodeListやNodeオブジェクトの内容を書き換える
ノードの削除
- p264 Node.removeChild()を利用
- 削除したいノードを取得して、取得したオブジェクト.parentNode.removeChild(取得したオブジェクト)で削除
innerHTML/textContent
textContent
- 子要素も含めたテキスト部分だけ設定・取得できる
- textContentに値を設定すると、子要素は全て削除されて、文字列だけ設定される
- p265 IEではinnerTextプロパティ
- DOM Level3 Coreにて定義
- タグ指定しても、そのまま文字列として表示される