JavaScriptでのDOM操作とは|さらに活用する3つの方法

- SE
- JavaScriptとhtmlはどのような関係なのでしょうか。
- PM
- JavaScriptによるDOM操作を解説しますので、一緒に見ていきましょう。
この記事でわかること
DOM操作とは?
DOM(Document Object Model)とは、JavaScriptでhtmlを参照・操作するときに使用される、Webブラウザがhtmlを解析したときに構築されるhtmlの構造です。
DOMの各要素をノードと呼び、ノード間の関係のモデルをWebブラウザが使い、htmlを表示します。DOMにはhtmlのDOMとcssのDOMがあり、それらは独立したものです。Webブラウザによってレンダリング時にリンクされます。
しかしJavaScriptからDOMを操作するときは、一般的に区別しません。この記事でも、DOMと呼べばhtmlのDOMもcssのDOMも指すことにします。
JavaScriptでの要素の指定方法について7つ
jQueryを使用せずに、JavaScriptでHTML要素を取得する方法、DOM操作を紹介します。id、セレクターでの検索、また、親子兄弟の要素の取得方法をサンプルコード付きで紹介しています。
初めに、JavaScriptでHTML要素を取得する時、取得したときに関係があるノードとDocumentオブジェクトについて説明します。
1:ノードについて
Nodeとは、様々なDOMAPIオブジェクト(HTML要素など)が継承しているインターフェースです。Nodeという同一のインターフェースを様々なAPIオブジェクトが継承することで、それぞれを同じようにJavaScriptで扱うことができます。
2:Document オブジェクトについて
Documentオブジェクトとは、Webページの構造(要素)をメモリ内に保持(表現)することで、それらをJavaScriptなどで制御しDOM操作できるようにしたものです。
DOMはDOMツリーというツリー構造で表現されています。そして、DOMのメソッドでツリーにアクセスし、スタイルやコンテンツの変更を行うことができます。
3:id 属性の検索について
DOM操作としてHTMLエレメントのidプロパティで検索を行う場合は、documentオブジェクトの「getElementById」メソッドを使用します。idを使用したHTML要素の取得方法のDOM操作以下のようにできます。
HTML
1
|
<div id="target">Hello,World!</div>
|
JavaScript
1
2
|
document.getElementById("target");
//<div id="target">Hello,World!</div>
|
4:セレクターの検索について
JavaScriptでHTML要素のセレクタ―検索しDOM操作をする場合は、documentオブジェクトの「querySelector」メソッドを使用します。querySelectorを使用した要素検索では引数に、CSSと同じセレクターを指定します。最初にマッチした要素が返されます。
HTML
1
2
3
4
5
|
<div id="selector-test">
<div class="div-1">one</div>
<div class="div-2">two</div>
<div class="div-3">three</div>
</div>
|
JavaScript
1
2
|
document.querySelector("#selector-test .div-2")
// <div class="div-2">two</div>
|
5:親要素の取得について
JavaScriptで親要素を取得するDOM操作の方法は大きく3つあります。「closest()」「parentElement」「parentNode」の3つで、すべて親要素を取得するものです。この3つは「closest()」と「parentElement」「parentNode」に分けることができます。
まず、「parentElement」「parentNode」は、指定されたノードのdomツリー上の親のノードを返します。2つは返すノードに少し違いがありますが基本的には同じです。
一方、「closest()」メソッドは、引数に指定されたセレクターを文書ルートまでさかのぼって要素を取得します。1階層上から、文書ルートまでの親要素を対象に検索しDOM操作することができます。
HTML
1
2
3
4
5
6
7
8
9
10
|
<div id="selector-test">
<div class="div-1">one</div>
<div class="div-2">two</div>
<div class="div-3">
three
<div class="div-3-1">
three-one
</div>
</div>
</div>
|
JavaScript
1
2
3
4
5
6
7
8
|
document.querySelector(".div-3-1").parentElement;
// <div class="div-3">...</div>
document.querySelector(".div-3-1").parentNode;
// <div class="div-3">...</div>
document.querySelector(".div-3-1").closest("#selector-test");
// <div id="selector-test">...</div>
|
6:兄弟要素を取得について
JavaScriptで同じ階層の一つ前、後などの兄弟要素を取得するDOM操作は、「previousElementSibling」または「previousElementSibling」プロパティを使用します。これらのプロパティで兄弟要素のDOM操作が可能です。
「previousElementSibling」が一つ前の要素、「previousElementSibling」が一つ後ろの要素を返します。
HTML
1
2
3
4
5
|
<div id="parent">親
<div class="child-1">子1</div>
<div class="child-2">子2</div>
<div class="child-3">子3</div>
</div>
|
JavaScript
1
2
3
4
5
|
document.querySelector("#parent .child-2").previousElementSibling
// <div class="child-1">子1</div>
document.querySelector("#parent .child-2").nextElementSibling
// <div class="child-3">子3</div>
|
7:子要素を取得について
JavaScriptで親要素、兄弟要素が取得するDOM操作ができたら、次は子要素を取得してみましょう。子要素の取得には最初の子要素、最後の子要素、子要素をリストで取得するDOM操作の方法などがあります。ここでは、それぞれのDOM操作をサンプルコード付きで紹介します。
HTML
1
2
3
4
5
|
<div id="parent">親
<div class="child-1">子1</div>
<div class="child-2">子2</div>
<div class="child-3">子3</div>
</div>
|
JavaScript
1
2
3
4
5
6
7
8
|
document.querySelector("#parent").firstElementChild
// <div class="child-1">子1</div>
document.querySelector("#parent").lastElementChild
// <div class="child-3">子3</div>
document.querySelector("#parent").children
// HTMLCollection(3) [div.child-1, div.child-2, div.child-3]
|
ループ処理を行う3つの場合
ここからは、ループ処理について紹介します。ループは繰り返し処理を行う場合に使用します。ループ処理は様々な種類がありますが、ここでは「for」「forEach」のループ処理について解説します。
1:for ループについて
DOM要素をforループするにはまず、配列で要素を取得します。先ほど子要素を取得したときのコードを使用すれば、リスト形式で要素を取得できます。
HTML
1
2
3
4
5
|
<div id="parent">親
<div class="child-1">子1</div>
<div class="child-2">子2</div>
<div class="child-3">子3</div>
</div>
|
JavaScript
1
2
3
4
5
6
7
8
|
let children = document.querySelector("#parent").children;
for (let i = 0; i < children.length; i++) {
console.log(children[i]);
}
// <div class="child-1">子1</div>
// <div class="child-2">子2</div>
// <div class="child-3">子3</div>
|
2:forEach ループについて
次に、forEachを使用したDOM要素のループ処理ですが、実は、.childrenなどで取得したHTML要素のリストはHTMLCollectionというオブジェクトで、forEachは使用できません。
Arrayのようにindex(添え字)でデータ取得はできますが、Arrayが持っている.forEachメソッドは持っていません。
JavaScript
1
2
3
|
document.querySelector("#parent").children.forEach();
Uncaught TypeError: document.querySelector(...).children.forEach is not a function
at <anonymous>:1:44
|
3:配列に変換する方法
HTMLCollectionではforEachをできませんが、配列(Array)に変換することで.forEachを使用できます。Arrayへの変換は以下のように行います。
JavaScript
1
2
3
4
5
6
7
8
9
|
let htmlCollection = document.querySelector("#parent").children;
let htmlArray = Array.from(htmlCollection);
htmlArray.forEach((value) => {
console.log(value);
});
// <div class="child-1">子1</div>
// <div class="child-2">子2</div>
// <div class="child-3">子3</div>
|
DOM操作における要素の属性値を取得・更新する
ここからは、DOM要素の属性値の取得から設定、また、要素の削除のDOM操作を紹介します。それぞれのHTMLタグは属性を持つことができます。属性値の取得、設定はDOM操作において基本なので習得しておきましょう。
全般的な取得・更新
DOM要素から属性値を取得するDOM操作は、getAttributeメソッドを使用します。逆に、更新するDOM操作は、setAttributeメソッドを使用します。
JavaScript
1
2
3
4
|
document.querySelector("#parent").getAttribute("id")
// "parent"
document.querySelector("#parent").setAttribute("id","test") // idがtestに変更される
|
クラス属性を利用
クラス属性を取得するDOM操作は、classNameプロパティを使用します。またはclassListを使用します。classListはクラスが一つずつ格納された配列で取得することができます。classNameでは、スペース区切りで取得できます。
HTML
1
|
<div id="class-sample" class="class1 class2"></div>
|
JavaScript
1
2
3
4
5
|
document.querySelector("#class-sample").className;
// "class1 class2"
document.querySelector("#class-sample").classList;
// DOMTokenList(2) ["class1", "class2", value: "class1 class2"]
|
DOM操作のオリジナルの属性を設定する
オリジナルな独自の属性を設定(取得)するDOM操作も、通常の属性値の取得、設定と同じです。
JavaScript
1
2
3
4
5
6
7
|
document
.querySelector("#class-sample")
.setAttribute("original", "独自属性です。");
// 対象のHTML要素:<div id="class-sample" class="class1 class2" original="独自属性です。"></div>
document.querySelector("#class-sample").getAttribute("original");
// "独自属性です。"
|
DOM操作の削除の仕方
DOM要素を削除するDOM操作は、.remove()というメソッドを使用するだけです。[削除したい要素].remove()で削除できます。
1
|
document.querySelector("#class-sample").remove();
|
DOM操作をさらに活用する3つの方法
DOM操作の活用として、HTML要素の追加、生成を紹介します。HTML要素を生成して、追加するという基本的なDOM操作にもなるので、ぜひこの操作を活用してDOM操作の基本を押さえましょう。
1:HTML要素を代入する
HTML要素を代入するDOM操作は、innerHTMLプロパティに直接HTMLタグを代入します。このとき代入するHTML要素は文字列でも構いません。
代入前
1
|
<div id="class-sample" class="class1 class2"></div>
|
JavaScript
1
|
document.querySelector("#class-sample").innerHTML = "<p>代入</p>";
|
代入後
1
|
<div id="class-sample" class="class1 class2"><p>代入</p></div>
|
2:引数へ生成したいHTML要素を指定する
HTML要素を生成するDOM操作は、.createElement()メソッドを使用します。これは、Documentオブジェクトのメソッドで、引数にはHTML要素のタグ名を指定します。
JavaScript
1
2
3
|
let newItem = document.createElement("div");
newItem.innerHTML = "Create Element";
document.body.append(newItem);
|
HTML
1
2
|
<div>Create Element</div>
</body>
|
3:HTML要素を追加し出力する
HTML要素を追加するDOM操作は、いくつかの方法があります。その一つに最後の子要素として追加する、appendChildメソッドがあります。ほかにはinsertBeforeなどがあります。ここでは、appendChildメソッドの紹介をします。
HTML
1
2
3
4
5
|
<div id="parent">親
<div class="child-1">子1</div>
<div class="child-2">子2</div>
<div class="child-3">子3</div>
</div>
|
JavaScript
1
2
3
|
let newItem = document.createElement("div");
newItem.innerText = "子4";
document.querySelector("#parent").appendChild(newItem);
|
HTML
1
2
3
4
5
6
|
<div id="parent">親
<div class="child-1">子1</div>
<div class="child-2">子2</div>
<div class="child-3">子3</div>
<div>子4</div>
</div>
|
DOM操作によるイベント処理について
DOM操作によるイベントは、基本的にユーザー操作から発生します。そして、ボタンクリックやマウスムーブなどの各イベントは、共通で「event」をインターフェースとしたオブジェクトで表されます。ここでは、そんなイベントについて紹介します。
オブジェクト化し処理を実行する
まず、DOMが読み込まれたときのイベント、「onload」イベントについて解説します。例えば、window.onloadイベントでは、DOMツリーの構造などが読み込まれたときに発揮されるイベントです。
JavaScript
1
2
3
|
window.onload = () => {
alert("Hello,World!");
};
|
同時に複数の処理を記述する方法
DOM要素にイベントを設定するDOM操作の場合は、通常「addEventListener」メソッドを使用します。addEventListenerで設定したイベントは上書きされず追加されていく形なので、複数設定した場合は、同時に実行することが可能です。
以下のサンプルコードでは、同イベントで複数の処理が実行されることが確認できます。
JavaScript
1
2
3
4
5
6
|
window.addEventListener("load", () => {
alert("イベント1");
});
window.addEventListener("load", () => {
alert("イベント2");
});
|
DOMレンダリングの効率化
DOM操作をマスターしたら次は、レンダリングの効率化、高速化です。Webサイトのページ表示速度はSEOに大きく影響があり、Googleも表示速度をSEO対策の一つとして重要視しています。
高速化させるためには様々な対策がありますが、ここでは外部ファイルを読み込むタイミングを意識したコーディングについて解説します。
外部ファイルの読み込み回りで意識することは、表示させたいWebページのコンテンツを先に表示させることです。そのために、外部ファイルは必要なモノのみコンテンツ表示前に読み込み、後回しでいいものはbodyの一番下に記述します。
変化する時間は極わずかだと思いますが、このような些細なことを積み重ねることで表示の早いサイト構築につながります。
- SE
- JavaScriptのコードを実行することで、htmlはこのように変化するのですね。
- PM
- 実際に自分でコードを実行させて、理解を深めていけると良いでしょう。
JavaScriptとHTMLの関係を理解しよう
この記事では、JavaScriptやjQueryによるDOMの操作を見て、実際のhtmlを変化させてみました。簡単にDOMが変わることに驚いた方もいるのではないでしょうか。
DOMの操作はフロントエンド開発の基本です。DOMを操作することによって、ページネーションやアニメーションが実行されます。
ここに挙げたjQueryはDOMを直接操作するライブラリでしたが、最近ではVue.jsなどといった、htmlのDOMとは別にJavaScript独自の仮想DOMを内部で持っておき、仮想DOMを操作の対象にして、ライブラリが仮想DOMが変化した場合htmlのDOMに反映させる、といったライブラリ(この場合フレームワークとも呼びます)も出てきています。
DOMを理解できなければフロントエンド開発は理解できません。この記事を取っ掛かりとして、DOMの理解を深めてください。
Search キーワード検索
Popular 人気の記事
-
【VB.NET入門】DataGridViewの使い方まとめ
公開: 更新:
reccomended おすすめ記事
-
【.NETが統合】.NET 5の概要と今後のリリース予定
公開: 更新:
Categories 連載一覧
Tags タグ一覧
Jobs 新着案件
-
遠隔テストサービス機能改修/JavaScript/東京都港区/【WEB面談可】/テレワーク
月給45万~60万円東京都港区(六本木駅) -
開発/JavaScript/東京都豊島区/【WEB面談可】/テレワーク
月給50万~50万円東京都豊島区(大塚駅) -
ECサイトの開発/HTML/東京都千代田区/【WEB面談可】/在宅勤務
月給26万~26万円東京都千代田区(秋葉原駅) -
官公庁向けシステム運用保守/C#/東京都府中市/【WEB面談可】
月給50万~60万円東京都府中市(中河原駅) -
官公庁向けシステム開発のテスター/C#/東京都府中市/【WEB面談可】
月給25万~35万円東京都府中市(中河原駅) -
システム開発部門でWeb系のプログラマー/埼玉県川越市/【WEB面談可】/在宅勤務
月給63万~63万円埼玉県川越市(南大塚駅)