2018/11/13

DOM、Node、Elementの違いとそれぞれの使い分け

仮想DOMのフレームワークを開発しその解説記事を書いているときに、自分がDOM、Node、Elementの違いを正確に理解していないことに気づいた。頭の中でふんわりとDOM≒Node≒Elementという理解になっていたのだ。

ということで、この3つの違いについて調べた。



DOM とは



Document Object Model は HTML と XML ドキュメントへの API です。これは、ドキュメントの構造的な表現、その内容を変更可能にすること、そして視覚的なプレゼンテーションを提供します。本質的には、ウェブページをスクリプト又はプログラミング言語と結合します。

DOM (Document Object Model) について - DOM | MDN

JavaScriptからHTMLドキュメントを操作するためのインターフェース、およびデータ構造のこと。JavaScriptからHTMLドキュメントに要素を追加したり、ボタンクリック時のイベントを登録したり、スタイルや属性を変更したり、要素のサイズや位置を取得したり、こういったものはすべてDOMのAPIを使うことで操作できる。

また、DOMはHTMLドキュメントを「オブジェクトのツリー」として扱っている。これを「DOMツリー」と呼ぶ。



Node とは



Node はいくつもの DOM API オブジェクトタイプが継承しているインターフェイスで、それらのさまざまなタイプを同じように扱える (同じメソッドのセットを継承する、または同じ方法でテストできる) ようにします。

Node - Web API インターフェイス | MDN

さきほどのDOMツリーを思い出してほしい。あのツリーのひとつひとつの箱(オブジェクト)がNode。たとえばfirstChildやparentNodeなどのプロパティ、appendChild、removeChildなどのメソッドはNodeが提供している機能だ。

また、Nodeにはいくつか種類がある。

  • Document
  • Element
  • Attr
  • CharacterData
  • などなど



Element とは



 Element は Document の中にあるすべての要素が継承する、もっとも一般的な基底クラスです。このインターフェイスは、すべての種類の要素に共通するメソッドとプロパティを記述するだけのものです。多くの具体的なクラスが Element を継承します。例えば HTML 要素には HTMLElement インターフェイス、SVG 要素には SVGElement インターフェイスなど。ほとんどの機能は、クラスの階層を下りると具体化していきます。

Element - Web API インターフェイス | MDN

さきほどNodeにはいくつか種類があると説明した。Elementは、そのNodeの中のひとつ、Element型のNodeのこと。HTMLの要素はElementを継承しておりElement<-HTMLElement<-HTMLDivElementのようになっている。

また、classListやinnerHTMLなどのプロパティ、getElementByIdやquerySelectorAll、setAttributeなどのメソッドはElementが提供している機能だ。



DOM、Node、Elementの関係


これらは継承関係にある、厳密には違うがシンプルに表すと以下のような図になる。
DOM
 |- Node
    |- Document
    |- Element
    |   |- HTMLElement
    |   |- HTMLDivElement
    |   |- HTMLInputElement
    |   |- ...
    |- Attr
    |- ...

NodeとElementの違いはわかりづらいが、instanceofを使うことでNode<-Elementの関係がわかると思う。
// Documentからdiv#appを取得する
const app = document.getElementById('app');
console.log('app instanceof Node:',           app instanceof Node); // true
console.log('app instanceof Element:',        app instanceof Element); // true
console.log('app instanceof HTMLDivElement:', app instanceof HTMLDivElement); // true

// appから子Nodeを取得する
const node = app.childNodes[0];
console.log('app.childNodes[0] instanceof Node:',    node instanceof Node); // true
console.log('app.childNodes[0] instanceof Element:', node instanceof Element); // false

// appから子Elementを取得する
const element = app.children[0];
console.log('app.children[0] instanceof Node:',    element instanceof Node); // true
console.log('app.children[0] instanceof Element:', element instanceof Element); // true



まとめ


ググったり、W3Cの仕様書を読んだりして、自分なりに3つをまとめてみた。

  • DOM
    • HTMLドキュメントとJavaScriptをつなぐインターフェース
    • DOMツリーはNode構成されている
  • Node
    • DOMツリーを意識して操作を行うときのオブジェクト
    • 例: appendChild、removeChild、parentNodeなど
  • Element
    • HTMLドキュメントの要素を意識して操作を行うときのオブジェクト
    • 例: style、attribute、width、heightなど




以上

written by @bc_rikko

4 件のコメント :

  1. これまでモヤッとしていた理解がきれいに言語化されました、とてもありがたい記事でした

    返信削除
    返信
    1. ありがとうございます!
      そう言っていただけて嬉しいかぎりですw

      削除
  2. 今までふわっと理解だったものが具体的に分かってきました。とても良い記事をありがとうございます!

    返信削除
    返信
    1. コメントありがとうございます!
      お力になれたようでなによりです!

      削除