「HTML、CSSはそれなりに書けるようになったけど、JavaScriptはググってコピペしている」
「jQueryから知ったため純粋なJavaScriptの長い文法が何をしているのかイマイチ理解できない」
「オリジナルでアニメーションを作るときに自分で作ったものが何故か動かないことが多い」
本日はそんな方に読んでもらいたい、「JavaScriptでのHTML要素の操作方法の基本」を紹介していきます。
最近ではWeb制作でもJavaScriptを使ったアニメーションが多用されるため、Webデザイナーやマークアップエンジニアの方でもJavaScriptを知らないといけなくなっています。
もちろんググれば作り方は出てくるのですが、そもそもの基本構文の説明まではされていないものが結構あるため「何となく」で作ることになっている人が多いと思います。
とはいえ基本的な内容は一度知れば「そんなもんか」となるはずです。
最後に簡単なモーダルを作る演習もあるのでぜひ最後まで読んでください。
また動画もあるので必要に応じて使ってください。
JavaScriptでHTML要素を取得する方法
まずはHTML要素の「取得」から紹介していきます。
HTML要素の取得が他の内容の根幹を担っているので、JavaScriptに苦手意識がある方もこれだけは知っておいて欲しいです。
まず簡単なHTMLだけ用意しておきます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<div class="div"></div>
</body>
</html>
上記のコードで<div class=”div”></div>という部分を取得したいときはこんな風に書きます。
const div = document.querySelector(".div");
console.log(div); // <div class="div"></div>と出力される
いきなりdocumentという見慣れない単語が出てきましたね。
こちら公式ドキュメントにも記載されているのですが、やや説明が難しく感じられるような書き方になっているのでチンプンカンプンになった方もいるのではないでしょうか。
https://developer.mozilla.org/ja/docs/Web/API/Document

こちらの説明は簡単に言い換えると「HTML要素の設計図にアクセスするためのもの」ということです。
documentを使うことでHTMLタグで構成された色んな要素にアプローチすることができます。
加えてdocumentには事前に便利な関数がたくさん用意されていて、それらの関数を使うことでHTML要素の操作が可能になっています。
先ほどのコードにある「querySelector」もdocumentに用意されている関数の一つで「引数に指定したセレクタに合う要素を取得」することを実現してくれます。
もう一度コードを見てみましょう。
const div = document.querySelector(".div");
console.log(div); // <div class="div"></div>と出力される
こちらのコードで「class名がdivになっているHTML要素を取得」という意味になっています。
取得したHTML要素は上記にあるように定数や変数に格納して、他の場所で使い回すことができます。
同じclass名が複数あったとき
ちなみにclass名は同じ名前のものが複数あるときがありますよね。
HTMLコードを少し書き換えてみます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<ul class="items">
<li class="item">1</li>
<li class="item">2</li>
<li class="item">3</li>
</ul>
</body>
</html>
「item」というclass名の要素が3つありますよね。
こんな時にquerySelectorを使うとどうなるのか見てみます。
const li = document.querySelector(".item");
console.log(li); // <li class="item">1</li>が出力される
無事に要素が取得できましたが、困ったことに1つしか出力されませんでした。
こちら公式ドキュメントにも記載があるのですが、querySelectorは条件に合う最初の要素しか取得できないという特徴があります。

そこで違う関数で「querySelectorAll」というものが用意されています。
const li = document.querySelectorAll(".item");
console.log(li); // NodeList(3) [li.item, li.item, li.item]と出力される
配列で3つの要素が取得できています。
class名は同じ名前を何回も使えるが故にJavaScript側での扱いには少し注意しましょう。
こちら配列なので個別に使いたいときには繰り返し処理で取り出す必要があります。
const li = document.querySelectorAll(".item");
console.log(li);
const liLength = li.length;
for(let i = 0; i < liLength; i++){
console.log(li[i]);
}
// <li class="item">1</li><li class="item">2</li><li class="item">3</li>と出力される
「querySelectorAll」の結果は配列になっているので、配列の中身はインデックス番号で区別できます。
そのためインデックス番号で各それぞれの要素を出力することができるわけですね。
特定の要素のみ取得したいとき
同じclass名が複数あるときに、「特定の1つのみ」を取得したいときはどうすれば良いのでしょうか?
幾つか方法があるのですが初学者向けに一番簡単な方法として、HTML側でidを指定しておくものがあります。
あらかじめHTML側でidを指定しておきましょう。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<ul class="items">
<li class="item" id="itemOne">1</li>
<li class="item">2</li>
<li class="item">3</li>
</ul>
</body>
</html>
classと違ってidは同じ名前を複数使うことができませんので、その特性を利用するわけです。
また「querySelector」でid名を指定するときは先頭が「#」になるので気をつけてください。
const li = document.querySelector("#itemOne");
console.log(li); // <li class="item" id="itemOne">1</li>と出力される
同じclass名が複数あったとしても、特定の1つの要素のみを取得することができましたね。
HTML、CSSでのコーディングだけだとidを指定する機会は無いので「idっていつ使うんだろう?」となったことがあるかもしれません。
JavaScriptではidをよく使うので覚えておきましょう。
親子関係の要素を取得する
下記のように親子関係になっているHTMLを取得するのも「querySelector」で実現できます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<ul class="items">
<li class="item" id="itemOne">1</li>
<li class="item">2</li>
<li class="item">3</li>
</ul>
</body>
</html>
const ul = document.querySelector(".items");
console.log(ul);

親子関係をまとめて取得したいときは親のセレクタを指定するだけで大丈夫です。
また子の要素だけを取得したいときは以下のようにすれば取得できます。
const ul = document.querySelector(".items").children;
console.log(ul); // HTMLCollection(3) [li#itemOne.item, li.item, li.item, itemOne: li#itemOne.item]と出力される
こちら複数要素になるので配列になっています。
さらに細かく分解したいときは先ほどのように繰り返し処理などで取得できます。
JavaScriptでHTML要素の作成をする方法
すでに書かれているHTMLコードから要素を取得することができたので、要素を新しく作る方法を紹介します。
まず下地に以下のようなHTMLがあるとします。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<div class="container">
<div class="item">テスト</div>
</div>
</body>
</html>

「テスト」とい文字が表示されていますね。
まずdivタグを作成してみたいと思います。
const div = document.createElement("div");
console.log(div); // <div></div>と出力される
要素の取得でも登場したdocumentの「createElement」という関数で簡単にHTMLタグを作ることができます。
続いてタグに挟むテキストも作成してみます。
const div = document.createElement("div");
// こちらを追加
div.innerHTML = "テスト";
console.log(div); // <div>テスト</div>と出力される
HTMLタグにテキストを追加するには「innerHTML」という関数を使います。
これで立派なHTML要素が完成しましたね。
しかし現状だと「作成しただけ」なので、画面に表示してみます。
const div = document.createElement("div");
div.innerHTML = "新規作成";
// こちらを追加
document.body.appendChild(div);

文章が2つに増えていますね。
画面に出力する際には「どこに表示するのか」という情報が必要になり、今回はbodyタグにしたので「document.body」となっています。
続けて「appendChild(作成した要素)」と書くことで、bodyタグのなかに作成したdivタグが表示されたわけです。
実務ではbodyタグに表示させるケースは多くはなくて、「特定の要素に入れ子で作成する」といった具合になります。
やり方は簡単で「親にしたい要素を取得する」ことさえ出来ればOKです。
こちら冒頭で紹介した「要素の取得」になりますよね。
現状は以下のようなHTMLの構成になっているとして、<div class=”container”></div>のなかに新規作成してみます。
画面には何も表示されていない状況です。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<div class="container"></div>
</body>
</html>
// ①親にする要素を取得
const container = document.querySelector(".container");
// ②HTMLタグを作成
const el = document.createElement("div");
// ③class名を作成
el.classList.add("test");
// ④テキストを作成
el.innerHTML = "テスト";
// ⑤①の子として表示させる
container.appendChild(el);
順番に説明していきます。
①まず作成する場所(親にする要素)を決めて取得します。こちらは冒頭に登場したquerySelectorを使っています。
②createElementでHTMLタグを作成します。こちらも先ほど紹介したcreateElementを使っています。
③②で作成したタグにclass名を作成しています。初めて紹介するのですがclassList.add(クラス名)とするとclass名を追加することができます。
④表示するテキストを作成します。こちらも先ほど紹介したinnerHTMLを使っています。
⑤①の子として新規作成したいのでappendChildを使っています。

画面にテキストが表示されていますね。
ブラウザの検証ツールでHTMLの構成も確認しておきましょう。

<div class=”container”></div>の子として入れ子状態でHTMLの新規作成が実現できているのが分かります。
ちなみに今やった内容は以下のような書き方でも実現できます。
const container = document.querySelector(".container");
const el = `<div class="test">テスト</div>`;
container.insertAdjacentHTML("afterbegin",el);

新規作成する要素は「“」を使って完成形を書くことでも大丈夫です。
先ほど紹介した方法と違って「タグ」「class名」「テキスト」を1行でまとめられるので楽ですよね。
insertAdjacentHTMLという関数が登場しましたが、第一引数に「場所」で第二引数に「作成した要素」を指定すれば、appendChildのように画面に表示することができます。
第一引数は公式ドキュメントにも記載ありますが、すでにキーワードが決められているので随時調べて選択してもらうと良いでしょう。
上記のコードでは「afterbegin」を使用しました。
https://developer.mozilla.org/ja/docs/Web/API/Element/insertAdjacentHTML

複製するだけのパターン
ちなみに新規作成と違って、「既にあるものを複製したい」という場面もあります。
下記のHTMLで<div class=”item”>テスト</div>の部分を複製してみたいと思います。
const copy = document.querySelector(".item").cloneNode(true);
document.querySelector(".container").appendChild(copy);

テストという文章が2つに増えていますね。
複製するときは「複製する対象を取得」する必要があり、そちらは冒頭で説明した「querySelector」で実現できます。
加えて「cloneNode(true)」と書くことで複製することができます。
JavaScriptでHTML要素を削除する方法
続いてHTML要素の削除を紹介します。
まずHTMLを以下のように想定します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<ul class="items">
<li class="item">1</li>
<li class="item">2</li>
<li class="item">3</li>
</ul>
</body>
</html>

リストが表示されていますね。
上記のHTMLにおいて、「class=”item”」となっている要素を削除したいと思います。
①削除する場所(削除対象の親要素)を取得
const items = document.querySelector(".items");
②削除する要素を取得
const item = document.querySelector(".item");
③削除を実行
items.removeChild(item);

リストが1つ消えていますね、順番に説明していきます。
①まず削除したい要素がある場所を指定する必要があります。とはいえ親要素になることがほとんどでしょう。要素の取得はquerySelectorで行います。
②続いて削除したい要素自身をquerySelectorで取得します。
③①に続けて「removeChild(削除する要素)」と書くと削除が実行されます。
ちなみに既に気付かれた方がいるかもしれませんが、「class=”item”」という要素は3つありました。
こちら冒頭で説明したようにquerySelectorで取得する際に、同じ名前が複数あった場合には「最初の要素のみ」を取得します。
そのため上記のコードでは1つしか削除されなかったんですね。
同じセレクタ名の要素を全て削除したいとき
では同じセレクタ名のものを全て削除したいときはどうすればいいのか、こちら先ほど紹介した繰り返し処理を使えば実現できます。
const items = document.querySelector(".items");
const itemAll = document.querySelectorAll(".item");
const itemLength = itemAll.length;
for(let i = 0; i < itemLength; i++){
items.removeChild(itemAll[i]);
}
同じセレクタ名のものを全て取得するにはquerySelectorAllを使えば良かったですよね。
こちら配列で取得されるので、繰り返し処理をしながら各要素はインデックス番号で指定できます。
上記のコードを実行することで画面から文字が無くなります。
同じセレクタ名があった際に特定の要素のみ削除したいとき
さらに同じセレクタ名で特定の要素のみ削除したいときも解説します。
冒頭で紹介した「idを指定する」という方法でも良いのですが、せっかくなので別の方法を紹介します。
HTMLは引き続き以下のような状態を使用します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./script.js" defer></script>
</head>
<body>
<ul class="items">
<li class="item">1</li>
<li class="item">2</li>
<li class="item">3</li>
</ul>
</body>
</html>

上記のコードで3番目の<li class=”item”>3</li>のみを削除したいとした場合、このように書くことでも特定の要素を指定したことになります。
const items = document.querySelector(".items");
const itemLast = document.querySelector(".item:last-child");
items.removeChild(itemLast);

3番目の要素のみ削除されていますね。
要素の取得に使用するquerySelectorの引数ではCSSの疑似クラスを使用することができます。
・最初の要素:first-child
・最後の要素:last-child
・2番目の要素:nth-child(2)
といった具合にCSSが分かる人なら大丈夫だと思います。
モーダルの実装方法
最後にここまで紹介した関数を組み合わせることで簡単なモーダルが作れるので紹介します。
慣れないうちはアニメーションは何だか難しい計算が必要に見えるのですが、結局のところ基本的な関数の組み合わせで再現できる場合が多いです。
まずHTMLから作っていきます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./style.css">
<script src="./script.js" defer></script>
</head>
<body>
<div class="container">
<button class="btn">詳細</button>
</div>
</body>
</html>

「詳細」と書かれたボタンが表示されていますね、こちらのボタンをクリックしたらモーダルが表示されることを目指します。
// ①ボタンを取得
const btn = document.querySelector(".btn");
// ②モーダルの親要素を作成
const modal = document.createElement("div");
modal.classList.add("modal");
// ③モーダルの子要素を作成
const inner = document.createElement("div");
inner.classList.add("inner");
// ④作成した②③を親子関係で作成
modal.appendChild(inner);
// ⑤取得した①のボタンがクリックされたときに⑤を表示するイベント
btn.addEventListener("click", () => {
document.body.appendChild(modal);
})
// モーダルの一部をクリックしたら画面から削除するイベント
inner.addEventListener("click", () => {
document.body.removeChild(modal);
})
想定している動きとしては、「ボタンをクリック→モーダルの表示→モーダルをクリック→モーダルの非表示」という内容です。
ボタンについてはすでにHTMLで作成済なのでquerySelectorで要素の取得だけ事前に実行しておきます。
モーダルについては新規作成になるのでcreateElementで作成します。
今回は細かく作り込みませんが実務ではモーダルのなかにテキストやボタン、画像を表示するはずなので中身が親子関係になるようなモーダルを作成しています。
// ①ボタンを取得
const btn = document.querySelector(".btn");
// ②モーダルの親要素を作成
const modal = document.createElement("div");
modal.classList.add("modal");
// ③モーダルの子要素を作成
const inner = document.createElement("div");
inner.classList.add("inner");
// ④作成した②③を親子関係で作成
modal.appendChild(inner);
~省略~
あとはaddEventListenerのイベント機能を使うだけです。
モーダルの表示は「ボタンのクリック」がきっかけになるので以下のような形になります。
~省略~
// ⑤取得した①のボタンがクリックされたときに⑤を表示するイベント
btn.addEventListener("click", () => {
document.body.appendChild(modal);
})
~省略~
モーダルは画面を覆い被さる形になるので、非表示の機能も必要です。
非表示といっても「要素の削除」をすれば良いはずですので、以下のような形で実現できます。
~省略~
inner.addEventListener("click", () => {
document.body.removeChild(modal);
})
これにて完成なのですが、モーダルと分かるようにCSSで装飾しておきましょう。
.modal {
width: 100%;
height: 50%;
position: absolute;
top: 0;
left: 0;
}
.modal .inner{
width: 100%;
height: 100%;
background: rgba(0,0,255,0.4) ;
}
簡単な見た目ですがモーダルを作成することができました。
意外と単純な仕組みですよね、こんな感じでHTML要素の操作の基本が分かれば色んなものを作れるので一度しっかり理解しておくことをおススメします。