当記事ではjQueryでは無く、素のJavaScriptのDOM操作について解説しています。

DOMの概念も解説しているので、ただコードをコピペするのではなく、「DOM操作とは何か」を理解出来るようになりますよ。

目次

DOMとは?

DOMとは「Document Object Model」の略で、ブラウザーがHTMLを解析する際に生成するデータ構造のことです。各要素は階層構造(ツリー構造)で表現されます。

JavaScriptでHTMLを操作したいとき、ソースとなるHTMLそのものを操作するわけでなく、DOMにアクセスして操作します。

コーディング時に意識することはないですが、DOMにアクセスする際、裏側ではDOM APIが使われています(※DOM APIとは、クライアントサイド WebAPIの内のひとつです)。

※参考:クライアントサイド Web API – ウェブ開発を学ぶ | MDN

補足:APIとは?

APIは、Application Programming Interfaceの略で、公開された技術のことです。APIを使うことで、第三者が開発したアプリケーション機能を活用できます。

身近なWebサービスでも多くのAPIが使われています。たとえば食べログなどでも、会員登録の際にGoogleやTwitterのアカウントでログイン出来る機能はAPIを利用して実装されています。

下は動的にHTMLを操作しているサンプルです。

htmlのコード

<p id="js-text">これはHTMLにかいてあるテキストです</p>
<button id="js-button">押してね!</buttton>

javascriptのコード

const button = document.getElementById("js-button");
const text = document.getElementById("js-text");
const changeText =()=>{
  text.textContent="→ DOMがテキストを書き換えました!"
}
button.addEventListener("click", changeText);

出力結果

DOM操作の基本的な目的

DOM操作の基本的な目的は、HTMLの操作です。

JavaScriptはDOMを参照する

Webページの見た目や構成を変更する際、JavaScript単体ではソースコード上から直接HTMLを取得することは出来ません。そこでDOMを通してHTMLを取得します。このことを「DOM操作」といいます。

ハンバーガーメニューのアイコン変化や、フォームに入力された内容のバリデーションなど、ユーザー操作にあわせて動的にWeb上の要素を追加・変化させる際にDOM操作が必要となります。

DOMツリーとは

DOMは、HTMLをツリー構造で格納しており、このツリー構造のことを、DOMツリーと呼びます。

DOMツリーは上の図ような流れで、HTMLのタグ・属性・テキストが階層構造で格納されています。階層構造は、HTMLのマークアップと同じ内容になります。

ツリーで構成される各要素を「ノード」と呼びます。

ノードとは

ノードとは、DOMツリーの階層構造を構成している個々の要素です。

ノード説明コード例
ルートノードDOMツリーの頂点のノード<html>
親ノード子要素を持つノードで、HTMLで親要素になっているタグ<div>
<p>↑親ノード</p>
</div>
子孫ノード他の要素に含まれているノードで、HTMLの子要素・孫要素<div>
<p>子孫ノード</p>
</div>
兄弟ノード同じ階層にある兄弟要素<p>兄弟ノード</p>
<p>兄弟ノード</p>
テキストノードHTMLタグに囲まれている文字<p>これがテキストノード</p>
コメントノードコメントのノード<!– これがコメントノード –>

HTMLタグはDOMの中で上記のいずれかのノードに当てはまる事になります。

DOM操作の際にJavaScriptは、DOMツリーのノードにアクセスして、HTMLタグの変更などを行います。

DOM操作を扱うための基礎知識

DOM操作をする前に、JavaScriptの基本的な知識について触れておきます。

オブジェクト・メソッド・プロパティの違い

JavaScriptはオブジェクト指向の言語なので、データをオブジェクトとして扱います。

オブジェクトとは、関連のあるデータとなる「プロパティ」の集合体です。

コーディングするときは、JavaScriptで用意されているWindowオブジェクトや、Documentオブジェクトなどを使用します。

オブジェクトを扱う過程で使用するのがメソッドとプロパティです。

オブジェクトプロパティメソッド
普通車エンジンを掛けてアクセルを踏んだら走る

オブジェクトの例

車の車種は属性を表すのでプロパティとなり、車を動かす方法は動作となるのでメソッドになります。

プロパティは、オブジェクト名の後に.(ドット)を付けて使用します。

例えば、WebページのURLを取得したい場合はlocation.hrefと書きます。.hrefの部分がプロパティです。

location.href;

続いてメソッドを見ていきます。メソッドは動作だと解説しましたが、その正体は関数です。オブジェクトの中に定義された関数のことをメソッドと呼びます。

メソッドは、オブジェクト名の後に.(ドット)を付けてさらにその後に()を付けます。

例えば、ページを更新するメソッドはwindow.reload()と書きます。.reload()の部分がメソッドです。

window.reload();

メソッドは、関数と同じように、何らかの処理を行ない、その結果を値として返します。

DocumentオブジェクトとWindowオブジェクト

実際にJavaScriptからDOMを取得するには、Documentオブジェクトを参照します。

DOMツリーはDocumentオブジェクトに格納されているため、Documentオブジェクトを通すことでHTMLが取得できます。

また、DocumentオブジェクトはWindowオブジェクトのプロパティです。

Windowオブジェクトは、ブラウザの情報を格納しているオブジェクトです。Documentオブジェクト以外に、ConsoleオブジェクトやEventオブジェクトをプロパティとして格納しています。

参考

DocumentオブジェクトとWindowオブジェクトは、ブラウザの検証ツールから閲覧出来ます。

検証ツールのコンソールタブをクリックして、windowと入力し、Enterキーを押すとWindowオブジェクトが表示されます。

表示されたWindowオブジェクトの「▶︎」をクリックすると、Windowオブジェクトが展開され、メソッドとプロパティの一覧が表示されます。

この中にdocumentプロパティがあります。

documentプロパティを展開すると、さまざまなメソッドやプロパティが確認出来ます。

JavaScriptでDocumentオブジェクトのメソッドやプロパティを使用する際は、オブジェクトの文法のルールでwindow.を付ける必要がありますが、Windowオブジェクトのみ省略出来ます。

例えば、指定したID属性を持ったHTML要素を取得するdocument.getElementById()は、window.を省略して使用できます。window.を付けても使用できますが、基本的には省略して書きます。

// window有り
window.document.getElementById();

// window無し
document.getElementById();

他にも、JavaScriptでデバッグする際に使用するconsole.logも、WindowオブジェクトのConsoleプロパティのメソッドですので、window.console.log()となりますが、省略してconsole.logと書きます。

// window有り
window.console.log();

// window無し
console.log();

DOM操作の頻出メソッド・プロパティ一覧

WindowオブジェクトとDocumentオブジェクトには、DOM操作をするためのメソッドとプロパティが定義されています。頻出のメソッドとプロパティを下記の表にまとめました。

メソッド

目的内容メソッド
検索idで要素を検索document.getElementById(id)
検索classで要素を検索document.getElementsByClassName(name)
検索name属性で要素を検索document.getElementsByName(name)
検索HTMLタグ名で要素を検索document.getElementsByTagName(name)
検索セレクターで合致するはじめの要素のみ検索document.querySelector(selectors)
検索セレクターで複数の要素を検索document.querySelectorAll(selectors)
属性取得HTMLの属性を取得element.getAttribute(name)
属性更新HTMLの属性を設定(上書き)element.setAttribute(name, value)
属性削除HTMLの属性を削除element.removeAttribute(name)
挿入対象要素の直前に挿入element.insertAdjacentElement(‘beforebegin’, object);
挿入対象要素の内部の最初に挿入element.insertAdjacentElement(‘afterbegin’, object);
挿入対象要素の内部の最後に挿入element.insertAdjacentElement(‘beforeend’, object);
挿入対象要素の直後に挿入element.insertAdjacentElement(‘afterend’, object);
生成HTMLタグで要素を作成document.createElement(name)
削除要素を削除element.remove()
削除子要素を削除element.removeChild()

プロパティ

内容プロパティ
親要素を取得parentNode
最初の子要素を取得firstElementChild
最後の子要素を取得lastElementChild
子要素リストを取得children
1つ前の要素を取得previousElementSibling
1つ後の要素を取得nextElementSibling
要素の高さを取得clientHeight
要素の幅を取得clientWidth
border-topの長さを取得clientTop
border-leftの長さを取得ClientLeft
複数の値を取得classList

DOM要素の検索

HTMLの要素を検索するコードを紹介します。

IDで要素を検索

document.getElementById(id);

getElementById() は、HTMLのID属性で要素を検索します。DOM操作の中でも使用頻度がかなり高いメソッドです。

classで要素を検索

document.getElementsByClassName(class);

getElementsByClassName()は、HTMLのclass属性で要素を検索します。指定した、class名を持つ要素をすべて取得します。

複数要素を取得するメソッドは、HTMLCollectionとして返ります(これ以降解説するメソッドも共通です)。

HTMLCollectionとは

HTMLCollectionとは、要素の一般的なコレクションとして表示される配列のオブジェクトです。

また、HTMLファイル全体では無く、特定の要素内でclassの検索も出来ます。

document.getElementById().getElementsByClassName(class);

getElementById()で取得した要素の中からclass属性を検索します。検索する範囲を絞れるので、特定の箇所のclassだけを取得したい場合に使えます。

nameで要素を検索

document.getElementsByName(name);

getElementsByName()は、HTMLのname属性で要素を検索します。指定した、name属性を持つ要素をすべて取得します。

HTMLタグ名で要素を検索

document.getElementsByTagName(tagname);

getElementsByTagName()は、HTMLのタグ名で要素を検索します。指定した、タグ名の要素をすべて取得します。

また、HTMLファイル全体ではなく、特定の要素内でタグの検索も出来ます。

// 指定したIDを持つ要素内でタグを検索する
document.getElementById(id).getElementsByTagName(tagname);

// 指定したclassを持つ要素内でタグを検索する
document.getElementsByClassName(class).getElementsByTagName(tagname);

このように検索範囲を絞れるので、特定の箇所のタグだけを取得したい場合などに使えます。

セレクタに合致する最初の要素のみ検索

document.querySelector(selectors); 

querySelector()は、指定したセレクタに合致する最初の要素を取得します。指定したセレクタが、複数存在しても、最初の要素しか取得しません。

querySelector()は、CSSのセレクタと同じ書き方で、取得する要素を指定します。

// classを指定
document.querySelector('.test');

// IDを指定
document.querySelector('#test');

// タグを指定
document.querySelector('div');

// 親要素の中にある子要素を指定
document.querySelector('.test p');

CSSのセレクタと同じ書き方なので、直感的で分かりやすいのがメリットです。上で挙げた例以外の指定方法ももちろん出来ます。

セレクタで複数の要素を検索

document.querySelectorAll(selectors);

querySelectorAll()querySelector()の複数形で、合致するすべての要素を取得します。セレクタの書き方はCSSと同じです。

属性値を取得

DOM操作でHTML要素の属性の値を取得する方法を解説します。

HTMLの属性を取得

element.getAttribute(attribute);

getAttribute()は、取得したい属性の名前で、HTML要素の属性の値を取得します。

classやidはもちろん、aタグのhref属性やimgタグのsrc属性の値も取得出来ます。

htmlのコード

<div id="hoge"></div>
<div class="hoge"></div>
<a href="https://example.com/"></a>
<img src="img/picture.jpg">

javascriptのコード

// 要素のidを取得
const getId = document.getElementById('hoge');
getId.getAttribute('id');
// 結果:hoge

// 要素のclassを取得
const getClass = document.querySelector('.hoge');
getClass.getAttribute('class');
// 結果:hoge

// aタグのhref属性を取得
const getAnchor = document.querySelector('a');
getAnchor.getAttribute('href');
// 結果:https://example.com/

// imgタグのsrc属性を取得
const getSrc = document.querySelector('img');
getSrc.getAttribute('src');
// 結果:img/picture.jpg

なお、getAttribute()はElementオブジェクトのメソッドなので、固有の要素の中から属性を取得します。

Documentオブジェクトのメソッドのように、HTMLファイル全体を対象に検索する事は出来ません。

HTMLの属性を設定(上書き)

element.setAttribute(name, value);

setAttribute()は、指定した属性の値を上書きします。引数に値を上書きしたい属性と、上書きする属性の値の2つを指定します。

htmlのコード

<a href="https://www.example.com"></a>
<img src="/img/picture.jpg" alt="">
<div></div>

javascriptのコード

// href属性の値を変更する
const getHref = document.querySelector('a');
getHref.setAttribute('href', 'https://www.hoge.com');

// src属性の値を変更する
const getSrc = document.querySelector('img');
getSrc.setAttribute('src', '/img/hoge.jpg');

// class属性を変更する
const getClass = document.querySelector('div');
getClass.setAttribute('class', 'hoge');

htmlのコード

<!-- 結果 -->
<a href="https://www.hoge.com"></a>
<img src="/img/hoge.jpg" alt="">
<div class="hoge"></div>

指定した属性が要素に無い場合は、そのまま属性が追加されます。

HTMLの属性を削除

htmlのコード

<div id="hoge" class="hoge">この要素から属性を削除します</div>

javascriptのコード

const getId = document.getElementById('hoge');
getId.removeAttribute('class');

// 結果:<div id="hoge">この要素から属性を削除します</div>

removeAttribute()は、指定した属性をHTML要素から削除します。

HTML要素の生成・削除

DOM操作で、HTML要素を生成・削除する方法を解説します。

HTML要素の生成

document.createElement(name);

createElement()は、指定したHTMLタグを新たに作ります。

javascriptのコード

// divタグを生成
document.createElement('div');

// pタグを生成
document.createElement('p');

// aタグを生成
document.createElement('a');

createElement()で生成したHTMLタグには、属性が無いため、既に紹介したsetAttribute()で属性を追加します。

javascriptのコード

// aタグを生成
const a = document.createElement('a');

// 生成したaタグにhref属性を追加
a.setAttribute('href', 'https://www.example.com');

// 結果:<a href="https://www.example.com"></a>

このようにしてcreateElement()で生成するHTMLタグに、setAttribute()で属性を追加出来ます。

HTML要素の削除

element.remove();

remove()は、指定したHTMLタグを削除します。

htmlのコード

<div>
 <div id="hoge">この要素が削除されます</div>
</div>

javascriptのコード

// hogeというid属性を持つ要素を取得
const getId = document.getElementById('hoge');

// id='test'を持つ要素を削除する
getId.remove();

htmlのコード

<!-- 結果 -->
<div>
</div>

メソッドの引数に削除するタグ名を指定するのではなく、削除したい要素を取得して、その要素本体に対してremove()を実行します。

HTML要素の挿入

HTMLにJavaScript側から要素を挿入する方法を解説します。

element.insertAdjacentElement(position, element);

insertAdjacentElement()は、指定の位置に、指定した要素を追加します。

追加する位置はJavaScript側で決められており、4ヶ所あります。

引数説明
beforebegin対象要素の前に挿入する
afterbegin対象要素の最初の子要素として挿入する
beforeend対象要素の最後の子要素として挿入する
afterend対象要素の後に挿入する

対象要素の直前に挿入

htmlのコード

<div id="hoge">対象要素です</div>

javascriptのコード

// 挿入先の要素を取得
const element = document.getElementByID('hoge');

// 挿入する要素を生成
const p = document.createElement('p');
p.textContent = 'この要素が前に挿入されます'; 

// 要素を挿入する
element.insertAdjacentElement('beforebegin', p);

insertAdjacentElement()の第一引数にbeforebeginを指定すると、対象となる要素の前に指定した要素が挿入されます。

htmlのコード

<!-- beforebeginの実行結果 -->
<p>この要素が前に挿入されます</p>
<div id="hoge">対象要素です</div>

対象要素の最初の子要素として挿入

htmlのコード

<div id="hoge">
  <p>↑に要素が挿入されます。</p>
</div>

javascriptのコード

// 挿入先の要素を取得
const element = document.getElementByID('hoge');

// 挿入する要素を生成
const p = document.createElement('p');
p.textContent = 'この要素が最初の子要素として挿入されます'; 

// 要素を挿入する
element.insertAdjacentElement('afterbegin', p);

insertAdjacentElement()の第一引数にafterbeginを指定すると、対象となる要素の中に最初の子要素として指定した要素が挿入されます。

htmlのコード

<!-- afterbeginの実行結果 -->
<div id="hoge">
  <p>この要素が最初の子要素として挿入されます</p>
  <p>↑に要素が挿入されます。</p>
</div>

対象要素の最後の子要素として挿入

htmlのコード

<div id="hoge">
 <p>↓に要素が挿入されます。</p>
</div>

javascriptのコード

// 挿入先の要素を取得
const element = document.getElementByID('hoge');

// 挿入する要素を生成
const p = document.createElement('p');
p.textContent = 'この要素が最後の子要素として挿入されます'; 

// 要素を挿入する
element.insertAdjacentElement('beforeend', p);

insertAdjacentElement()の第一引数にbeforeendを指定すると、対象となる要素の中に最後の子要素として指定した要素が挿入されます。

htmlのコード

<!-- beforeendの実行結果 -->
<div id="hoge">
 <p>↓に要素が追加されます。</p>
 <p>この要素が最後の子要素として挿入されます</p>
</div>

対象要素の直後に挿入

htmlのコード

<div id="hoge">対象要素です</div>

javascriptのコード

// 挿入先の要素を取得
const element = document.getElementByID('hoge');

// 挿入する要素を生成
const p = document.createElement('p');
p.textContent = 'この要素が後に挿入されます'; 

// 要素を挿入する
element.insertAdjacentElement('afterend', p);

insertAdjacentElement()の第一引数にafterendを指定すると、対象となる要素の後に指定した要素が挿入されます。

htmlのコード

<!-- afterendの実行結果 -->
<div id="hoge">対象要素です</div>
<p>この要素が後に前に挿入されます</p>

jQueryではなく素のJavaScriptを使えた方がいいの?

ここまで記事を読んできた方の中には、「jQueryを使えば出来ることを、わざわざ素のJavaScriptで書く必要があるの?」と思った方もいるかもしれません。

そもそもjQueryは下記の役割を持たせるために開発されました。

  • JavaScriptで書くと煩雑になりがちなコードをカンタンに記述するため
  • ブラウザ間でサポートされているコード差を埋めるため

ただ、jQuery本体のファイルの容量が大きいため、Webサイトの表示パフォーマンスの面ではあまり良くありません。また、コードの処理速度の面でもJavaScriptの方が処理速度が速いです。

ただ近年では、JavaScriptでもDOM操作に便利なメソッドやプロパティが導入されたり、ブラウザ間でのコード差も少なくなってきており、上記のjQueryを使用するメリットが薄くなってきています。

こういったWebを取り巻く技術の進化から、JavaScriptを学習する事で得られるメリットは大きいです。

JavaScriptを学習する事で、jQueryで書いていたコードの理解が深まりますし、関数やオブジェクトの理解を深めれば、より綺麗で保守性が高いコードが書けるようになります。

チェックテスト

チェックテスト下記、コードにおいて、下記表示をするために必要なcssプロパティはどれかdiscordにて共有ください。

TOP