JavascriptによるDOMの取得や操作のデモを示すことで、DOMの手触りを持った理解を得ることを目標とします。
DOMとは何か?
DOMとは簡単にいうと以下のようなものです。「Webページの要素やコンテンツなど」とありますが、これはHTMLのタグをイメージすると良いでしょう。
DOMとはドキュメントオブジェクトモデル (Document Object Model)の略で、Webページの要素やコンテンツなどをツリー構造で表現したデータモデルのことです。
出典:https://prog-8.com/docs/dom
ではそのようなツリー構造を作成することの何が嬉しいのでしょうか。それは、mdnで以下のように説明されています。「ウェブ文書のためのプログラミングインターフェイス」とは、簡単のために大胆に言ってしまえば、HTMLを外部から扱いやすいようにする表現形態とでも言えるでしょう。
つまりHTMLのような文書をツリーモデルとして表すことで、Javascriptによる操作を行えるようになるということです。そのような意味でmdnの定義の方がしっくりくる定義ですが、わかりやすさのため先に上記の定義を紹介しました。
ドキュメントオブジェクトモデル (DOM) はウェブ文書のためのプログラミングインターフェイスです。ページを表現するため、プログラムが文書構造、スタイル、内容を変更することができます。 DOM は文書をノードとオブジェクトで表現します。そうやって、プログラミング言語をページに接続することができます。
出典:https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model/Introduction
概念?実際はどこにいるの?
HTMLからツリーのような構造が定義できるということはわかる、でもそれはどこにいるのだろうか?と思いませんか。(自分は最初思いました)
結論から言うとこれは、ブラウザにいます。ブラウザはHTMLなどのコードを読み込むと、それを解析して最終的には画面を表示します。(この一連の動作をレンダリングと言います。) ここで、解析を行なってから表示されるまでにはいくつかのステップがあるのですが、その一ステップとしてDOMの構築があり、そこでDOMが構成されるのです。
レンダリングのプロセスについては以下の記事が詳しいです。
- https://zenn.dev/ak/articles/c28fa3a9ba7edb
- https://web.dev/articles/critical-rendering-path/constructing-the-object-model?hl=ja
DOMのノードを取得する
ブラウザ上でHTMLをもとにDOMが構成されますが、そのDOMの内容を確かめたり、DOMを操作(追加、削除、変更)するための言語がJavascriptです。
DOMの取得方法にはいくつか方法があります。
id値から取得
document.getElementById(id);
HTMLのidをもとにDOMノードを取得することができます。例えば、以下のようなHTML要素が存在する場合は引数に"price"を入れることでこの要素を取得できます。
<p id="price">150円</p>
セレクター式で要素を取得
document.querySelector(selector);
セレクター式とは「#price-list li.fish」であれば、id="price"の要素の配下からclass="fish"の<li>要素を取得します。
セレクター式で複数の要素を取得
document.querySelectorAll(selector);
先ほどまでは単一のノードを返していましたが、これにより条件に一致する全てのノードをリストとして取得できます。
DOMのノードをいじる
取得したDOMノードについては、Javascriptで内容を変更したり、イベントリスナー(クリックやホバーされた時の挙動)を追加したりすることができます。
取得した要素のことをElementオブジェクトといいます。
このElementオブジェクトのプロパティをいじることで文字やスタイルなどを変更できます。
テキストを変更する
let elem = document.getElementById("price");
elem.textContent = "200円"
hover時のイベントを追加する
let elem = document.getElementById("price");
elem.addEventListener("mouseenter", function() {
console.log("hover");
}, false);
DOMのノードの追加
ノードを追加する時は、以下の流れで行います。データ構造でいうLinked Listの新しいノードを定義して、他のノードからnextで繋げるような実装と似ています。
- ノードの作成
- ノードの組み立て
// 作成
let section = document.querySelector("#section");
let paragraph = document.createElement('p');
paragraph.textContent = "Hello!";
// 組み立て
section.append(paragraph);