5分でわかる!DOMとはなにか

  • ブックマーク
  • -
    コピー

 DOMはDocumentObjectModelの略です。

大将

なんですかそれ

 「ドキュメントを物として扱うモデル」ということです。プログラムからHTMLやXMLを自由に操作するための仕組みのことですね。例えばブラウザに表示される文字の色を変更したり、大きくしたりと、Webページの見た目をプログラムで処理をしたいときがあると思います。しかし何もしていない状態のHTMLファイルではJavaScriptからなにか操作をすることができません。そこでファイルの特定の部分に目印を付けて、その部分を操作したい、ということです。

 ドキュメント内の各要素にアクセスする方法を提供するHTMLまたはXML要素構造の階層表現は、ツリー構造をとっています。ドキュメントは、スクリプト言語(JSなど)がそれらに接続しやすくするオブジェクトあるいはノードとして表示されます。

大将

ノードという言葉はよく出てくるんで、慣れておきましょう!

 HTMLまたはXMLページは、実際のページまたはブラウザウィンドウのソースとして表示できます。ページをページとして表示するには、ドキュメントをリクエストするだけで、ブラウザがドキュメントを解析し、表示してくれます。 ソースとして表示するには、コマンドCtrl + Uをするか、ブラウザタブで右クリックして[ページソースの表示]を選択すると、ソースを閲覧できます。

大将

ここら辺はSUNABACOプログラミングスクールでも勉強しますね!

 JavascriptでDOMを操作する方法の有名な例として、getElementByIdgetElementsByTagNameがあげられます。これらは、特定の基準に一致するすべての要素のリストを返します。

var inputs = document.getElementsByTagName("input");

 JavaScriptとDOMは緊密に絡み合っていましたが、時間の経過とともに徐々に2つの別個のエンティティに進化しました。通常、ページコンテンツはDOMに保存され、JavaScriptによる操作にアクセスが可能です。 DOMはプログラミング言語ではなく、プログラミングインターフェースであるため、JavaScriptとHTMLのみで使用されるだけではありません。次のように、Pythonでも操作できます。

import xml.dom.minidom as m
document = m.parse("C://code/xml_data.xml");
document.nodeName #DOM property of the document object
table_list = document.getElementsByTagName("table");

 ご覧のとおり、DOMはプラットフォームに依存しないように設計されているため、すべてのプラットフォームで構造表現にアクセスできます。 DOMを操作する最も一般的なケースはJavaScriptとHTMLを使用することですが、他のマークアップ言語とスクリプト言語も使用できます。

大将

スクールでは主にJSからの操作だけやりますね!

DOMにどうやってアクセスするのか

 DOMにアクセスできるのは、ドキュメントの読み込みが完了した後のみです。

 ブラウザーが異なればDOMのバリエーションも異なります。

 安全上の理由から、DOMアクセスコードをwindow.onload関数でラップする必要があります。

 ページが読み込まれると、HTMLコードに無いドキュメント要素とウィンドウ要素のAPIの使用ができるようになります。ドキュメントはhtmlマークアップテキストを表し、ウィンドウはhtmlマークアップテキストを表示するブラウザウィンドウを表します。
 新しいh1要素を作成し、要素にコンテンツを追加し、DOMに要素を追加するという例で、より理解を深めましょう。

window.onload = function(){
var heading = document.createElement("h1");
var headingContent = document.createTextNode("hogehoge");
heading.appendChild(headingContent);
document.body.appendChild(heading);
}

インターフェースとオブジェクト

大将

DOMは混乱しますよね。

 たとえば、form要素はHTMLFormElementインターフェースからnameプロパティを取得しますが、そのclassNameプロパティはHTMLElementインターフェースから継承されます。
 多くのオブジェクトは異なるインターフェースから継承します。

let table = document.getElementById("hogehoge");
var tableAttributes = table.attributes;
tableAttributes.forEach( (attribute) => { 
if(attribute.nodeName.toLowerCase() == "border")
  table.border = "1";
}
table.summary = "Increased border";

 上記の例からわかるように、Elementインターフェイスから派生したプロパティnodeNameを使用すると同時に、テーブルに固有のプロパティを使用して、すべてのプロパティを繰り返し処理し、「border」に一致するプロパティを見つけることで、テーブルの境界線をtable.border = "1"再調整しています。

大将

これは数あるうちの一つの例ですので、他にも色々試してみましょう。

DOMのデータタイプ

 多くのデータ型がDOMに渡されています。最後にいくつかのデータ型について簡単に説明しましょう。

  • ドキュメント:オブジェクト、ルートドキュメント。
  • element:DOMAPIのメンバーによって返されるelement型のノード。
  • nodeList:document.getElementsByTagName()やdocument.getElementsByClassName()などの複数の結果を返すDOMメソッドによって主に返される要素の配列。インデックスによって繰り返しアクセスできる。
  • 属性:属性は類似したノードであり、要素と同じように扱われるが、クラス、ID、名前、タイプなどの特定の要素のプロパティを提供する。
  • namedNodeMap:これは配列に似ているが、名前またはインデックスで名前にアクセスできる。前者はJSでは機能しないが、Pythonリストではうまく機能する。 namedNodeMapには、リストからアイテムを追加および削除するためのitem()メソッドもある。これは、インデックスを使用してアイテムにアクセスすることは、列挙の便宜のために追加されただけ。

まとめ

 DOMはよくわかりそうで、よくわかってないって人が多いと思いますが、プログラムからHTMLやXMLを自由に操作するための仕組みと頭に入れておきましょう。

 DOMは重要なインターフェースです。実際のDOMを模倣する仮想DOMは、Reactが仮想DOMを操作して、元のDOMにマップするようになこともあります。

大将

バニラJSを書くことはほとんどないので、むしろこちらの方が多いですね。私は。仮想とオリジナルの2つのDOM間の情報関係は、量子テレポーテーションに似てますね。興味ありますか?

References

https://medium.com/@onejohi/an-introduction-to-dom-f22f9d92faca
https://developer.mozilla.org/ja/docs/Web/API/GlobalEventHandlers/onload
  • ブックマーク
  • -
    コピー