はじめに
JavaScriptの学習を進める中で、DOMの仕組みが分からず苦戦した、または現在まさに苦戦しているという経験をお持ちの方は多いのではないでしょうか?私もその中の一人ですが、DOMの仕組みを理解したことで、それまでなんとなく行っていたDOM操作の理解が深まりました。もし、DOM操作をなんとなく使えても、その仕組みが分からないと感じているのであれば、DOMを知ることで理解が深まる可能性があります。
何事も基本が大事と言いますが、基礎部分を学ぶことは時に退屈で遠回りに感じるかもしれません。しかし、基本を理解しておくことは、今後のプログラミング学習において非常に重要です。今回はWebの基本であるDOMについて解説します。
この記事について
目的
- DOMの仕組みについて知る
- JavaScriptでのDOM操作をできるようにする
対象者
- 初学者の方
- DOMの基本的な仕組みを知りたい方
- Webの理解を深めたい方
DOMとは
DOMについて、MDN Web Docsでは以下のように説明されています。
ドキュメントオブジェクトモデル (Document Object Model, DOM) は、ウェブページを表す HTML のような文書の構造をメモリー内に表現することで、ウェブページとスクリプトやプログラミング言語を接続するものです。 引用:MDN Web Docs - ドキュメントオブジェクトモデル (DOM)
これは、DOM(Document Object Model)がHTMLやXMLドキュメントの構造をプログラムで操作し、スタイルや内容を変更できる仕組みであることを意味します。HTMLやXML文書をWebページとして画面にレンダリングする際に、プログラムから表示内容の変更が可能になります。(この記事では、主にHTMLファイルをベースに解説します)
DOMはHTMLに含まれる要素(エレメント)を、ノードとオブジェクトで表現します。
-
要素(エレメント)
HTMLの文書を構成する基本単位で、開始タグ、内容、終了タグから成り立ちます。例えば、
<div>テキスト</div>
などのタグとその中のテキストなどが含まれます。要素はページの内容やレイアウトを決めるための部品です。 -
ノード
DOMの1つ1つの要素のことをノードと呼びます。ノードには、要素ノード、テキストノード、コメントノードなどがあり、ドキュメント内のすべての構成要素を表します。
-
オブジェクト
ドキュメント内のすべてのノード要素のことを指します。これらのノードはオブジェクトとしてJavaScriptなどのプログラムから扱うことができ、文書の内容や構造を動的に変更することが可能です。
プログラムを使用しDOM操作をすると何ができるか
プログラムを使用しDOM操作をすると何ができるか、例と共に見てみましょう。
以下のようなTodoリストがあったとします。ボタンをクリックすると、フォーム内に入力した文字をリストに追加します。
このようなTodoリストの一連の流れの中で、DOMは以下のように変更されて画面に表示されています。
- フォームに入力した文字列を取得
- リストのノード(この場合は
<ul>
タグなど)を取得 - 1と2の工程で取得したデータを使用してリストを追加
実際のプログラムはもう少し細かい動きとなりますが、入力した文字をリストに追加するにはこのような流れとなります。DOMの仕組みを利用することにより、アプリケーションの表示内容を動的に変更することが可能になります。
DOMツリーについて
DOMは、HTMLドキュメントの内容を解析し、ツリー構造で表現します。Webページを例に説明すると、ブラウザがHTMLを読み込むと、最初にDOMツリーを生成します。DOMツリーは、ドキュメント内の要素をノードとして階層構造で表現します。DOMをツリー構造で表現することにより、プログラムが1つ1つのノードにアクセスできるため、プログラムを通じて要素の変更などの操作が可能となります。HTMLのコードを例に詳しく見ていきましょう。
以下のWebページがあったとします。
このWebページのHTMLファイルは、以下の記述内容となります。
<html lang="ja">
<head>
<title>DOMとは</title>
</head>
<body>
<h1>Hello World!</h1>
<h2>エンベーダー</h2>
</body>
</html>
このHTMLファイルをDOMは以下のツリー構造で表現します。各要素はノードとして階層構造でDOMツリーが作成されます。これにより、プログラムは特定のノードにアクセスでき、さまざまな操作が可能となります。
DOMツリーの基本構造
ツリー構造で表現された1つ1つのノードは、すべてオブジェクトです。各ノードの内容は以下の通りとなります。
-
documentノード
DOMツリーの最上位には「documentノード」があります。メタデータなどを含む、ページ全体を管理しており、プログラムでツリー内の子要素にあたるノードにアクセスする際のエントリーポイントとなります。
-
htmlノード
documentノードの子要素として、「htmlノード」があります。HTML文書の具体的な内容を持つルート要素であり、ページのすべてのコンテンツを含んでいます。
-
要素ノード
HTMLタグ(例えば
<div>
,<p>
,<a>
など)は「要素ノード」としてDOMツリーの各部分を形成します。要素ノードは親子関係を持ち、入れ子になった構造を取ります。 -
テキストノード
要素ノードの中にはテキストが含まれていることがあります。このテキスト部分は「テキストノード」として表現されます。今回の例では、「Hello World!」と「エンベーダー」がテキストノードです。テキストノードは文字列だけを含み、子の要素は持ちません。
-
属性ノード
HTMLタグが持つ属性(例えば
id
,class
,src
など)は、「属性ノード」として要素ノードに関連付けられています。
この階層構造の理解は、DOMでの操作をするために重要です。Webページはただのテキストファイルではなく、ブラウザが表示するための複雑な構造を持っています。この構造をDOMツリーとして理解することで、どの部分がどのように関連しているのかがわかりやすくなります。
DOMの操作方法を知る
DOMの基本を知ったところで、次に実際にどのようにプログラミング言語でDOM要素を操作するかを説明します。DOM操作で最もよく知られている言語はJavaScriptです。JavaScriptは、Webブラウザ上でDOM操作をする言語として、広く使用されています。この記事では、JavaScriptを使用したDOMの操作方法を紹介します。
JavaScriptはWeb上で直接実行され、ユーザーがWebページを閲覧している間に、ページの表示内容を動的に変更することができます。JavaScriptには、DOMを操作するためのWebAPIが用意されており、開発者がHTML要素を操作し、ページの表示内容を容易に操作することができます。
ここから、DOM操作において使用頻度の高い構文を紹介します。
DOM要素の取得
DOMの操作をするためには、まず操作対象の要素を取得する必要があります。要素を取得し、その取得した要素に対してDOM操作を行うというのが一般的な流れになります。以下は、要素を取得するための主要な方法です。
-
指定したID属性を持つノードを返します。
DOMツリー内に指定した属性をもつIDは1つしかないため、素早くノードを取得したい場合に使用されます。
document.getElementById('id名')
-
指定したclass属性の文字列を持つ要素をすべて取得します。
getElementsByClassName('クラス名')
-
指定したname属性の文字列を持つすべての要素を取得します。
getElementsByName('name属性の値')
-
指定したCSSセレクターに一致する最初の要素を1つ返します。
querySelector('CSSセレクター')
-
指定したCSSセレクターに一致するすべての要素を取得します。
querySelectorAll('CSSセレクター')
DOM要素の操作
DOM要素を取得した後、その要素に別の要素を追加したり、要素を変更することが可能になります。取得したDOM要素を変更したり、他の要素を追加する方法は以下の通りです。
-
DOM要素の作成
指定した要素を作成します。
document.createElement('タグ名')
-
DOM要素の追加
指定した要素を指定された親要素に追加します。
parentElement.appendChild(新しい要素)
-
DOM要素の属性の変更
指定した要素の属性を変更します。
element.setAttribute('属性名', '新しい値')
-
DOM要素の内容を変更
指定した要素の内容が変更されます。
element.innerHTML = '新しい内容';
Todoリストを作成してDOM操作の理解を深める
さまざまなDOM操作の記述を学びました。次に、実際にコードを記述して理解を深めましょう。このセクションでは、以下のTodoリストを作成します。
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Todo</title>
</head>
<body>
<h1>Todoリスト</h1>
<form id="todo-form">
<input type="text" id="todo-input" placeholder="新しいタスクを入力" />
<button type="submit">作成</button>
</form>
<ul id="todo-list">
<li>todo1</li>
<li>todo2</li>
</ul>
<script src="./todo.js"></script>
</body>
</html>
todo.js
const form = document.getElementById('todo-form');
const input = document.getElementById('todo-input');
const todoList = document.getElementById('todo-list');
form.addEventListener('submit', function (event) {
event.preventDefault();
const newTask = input.value.trim();
if (newTask !== '') {
const listItem = document.createElement('li');
listItem.textContent = newTask;
todoList.appendChild(listItem);
input.value = '';
}
});
コードを作成してブラウザで開くと、以下のようにフォームに入力したリストがtodo2の下に追加されることが確認できるかと思います。
リストが追加される際のDOMの状態は以下のようになり、ui
ノードの子要素としてli
ノードが追加されます。
では記述したJavaScriptのコードの詳細を確認しましょう。
DOM要素の取得
document.getElementById()
メソッドを使用し、html内のid要素を取得してそれぞれの変数に代入します。
const form = document.getElementById('todo-form');
const input = document.getElementById('todo-input');
const todoList = document.getElementById('todo-list');
フォームの送信イベントリスナーの設定
次に、フォームが送信されたときの動作を定義します。
-
form.addEventListener('submit', function (event)
フォームが送信されるときに実行されるイベントリスナーを設定します。イベントリスナーとは、ユーザーがボタンをクリックしたり、フォームを送信したり、キーを押したりしたときに、それに応じて特定の関数を実行する仕組みです。
-
event.preventDefault():
フォームのデフォルトの送信動作(ページのリロード)を防ぎます。これは、ページがリロードされず、JavaScriptで定義した動作のみが実行されることを意味します。これにより、フォームに入力されたタスクをページ全体の再読み込みなしにTodoリストに追加し、変更された一部のみをDOMに反映することができます。
form.addEventListener('submit', function (event) {
event.preventDefault();
新しいタスクの追加
次に、フォームに入力されたタスクをリストに追加する部分です。記述したコードの内容は以下の通りです。
-
const newTask = input.value.trim();
入力フィールドの値を取得し、
trim()
メソッドを使用して前後の空白を削除した文字列をnewTask
という変数に代入します。 -
if (newTask !== '') {
入力されたタスクが空でないことを確認し、空の場合は何もせずに処理を終了します。
-
const listItem = document.createElement('li');
document.createElement
メソッドを使用して、<li>
要素を作成し、listItem
という変数に代入します。 -
listItem.textContent = newTask;
newTask
に代入されている入力フィールドのテキスト内容を、listItem
に代入されている<li>
タグ内のテキストに設定します。 -
todoList.appendChild(listItem);
新しく作成したリストアイテムを、Todoリストの
<ul>
要素に追加します。 -
input.value = '';
入力フィールドを空にして、次の入力の準備をします。
const newTask = input.value.trim();
if (newTask !== '') {
const listItem = document.createElement('li');
listItem.textContent = newTask;
todoList.appendChild(listItem);
input.value = '';
このように、JavaScriptのWebAPIを使用すれば、さまざまなDOM操作をすることが可能になります。ユーザーが操作した内容を動的に変更し、ブラウザに表示することができます。今回紹介した構文を使用し、さまざまなDOM操作を試してJavaScriptの理解を深めていきましょう!
この記事で学んだこと
-
DOMとは
DOMとは、HTMLやXMLドキュメントの構造をプログラムで操作し、スタイルや内容を変更することができる仕組みです。HTMLやXML文書をWebページとして画面に表示する際に、プログラムから表示内容の変更が可能となります。
-
DOMツリーについて
DOMは、HTMLなどのドキュメントの内容を解析し、ツリー構造で表現します。DOMツリーはドキュメント内の要素をノードとして、階層構造で表現します。DOMをツリー構造で表現することにより、プログラムを通じて要素の変更などの操作が可能となります。
-
DOMの操作方法
この記事ではJavaScriptを使用したDOMの操作方法を紹介しました。DOMの操作をするためには、まず要素を取得する必要があります。要素を取得する方法から、その取得した要素を変更するなどの操作を学びました。
参考資料
以下のリンクは、この記事で説明した手順や概念に関連する参考資料です。より詳しく学びたい方は、ぜひご参照ください。
-
MDN Web Docs
https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model
https://developer.mozilla.org/ja/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents
-
Javascript.info - DOM ツリー
-
web.dev -ブラウザの仕組み
https://web.dev/articles/critical-rendering-path/constructing-the-object-model?hl=ja
-
W3C - What is the Document Object Model?
【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。
「フリーランスエンジニア」
近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。
「成功する人とそうでない人の違いは何か?」
私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。
比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。
多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、
エンベーダー編集部
エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。
関連記事
2020.02.25
完全未経験からエンジニアを目指す爆速勉強法
USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話
- キャリア・学習法
- エンジニア
2024.10.22
Reactの基本、useMemoを理解しよう
この記事では、useMemoに焦点を当て、詳しく解説します。useMemoは、関数の結果をメモ化し、再レンダリング時に不必要な再計算を避けることができる仕組みです。それでは、一緒に学んでいきましょう。
- React
- フロントエンド
2024.03.24
JavaScriptって何?レベルの初心者がとりあえず触ってみるハンズオン
このハンズオンを通じて、プログラミング初心者やJavaScriptに苦手意識を持つ方でも、JavaScriptの使い方を基礎から簡単に学べます。特別な経験や知識は一切必要ありません。パソコンとインターネットの基本操作ができれば、準備は完了です。わからないことがあっても大丈夫。一旦はこういうものだと思って進めてみてください。
- ハンズオン
- JavaScript
- フロントエンド
2024.08.17
Reactの基本、useEffectを理解しよう
フロントエンドエンジニアを目指す方や、初めてReactを学ぶ方に向けて、この記事ではReact HooksのuseEffectについて解説します。useEffectの仕組みは少し複雑で初学者の方にとって難しく感じるかもしれませんが、Reactでの開発では必須の技術となります。useEffectの基本を押さえておくことで、これからのReact学習の理解度が深まります。基本を学び、フロントエンドエンジニアへの道を進んでいきましょう!
- プログラミング
- React
- フロントエンド