Day16 後半のゴール
後半では、createElement と appendChild を
「ただ要素を増やす道具」から
「小さなUIコンポーネントを組み立てる道具」にレベルアップさせます。
ここでつかみたいのは、この感覚です。
Day16 後半で意識したいポイント
1つの「まとまり」(カード・行・メモ)を、複数の要素で組み立てる
createElement と appendChild を“入れ子”にして、階層構造を作る
1つの「カード」を組み立てるイメージ
目標とする見た目
例えば、こんな「メモカード」を作りたいとします。
タイトル(太字)
本文(普通のテキスト)
HTML で書くならこうです。
<div class="card">
<h2>タイトル</h2>
<p>本文テキスト</p>
</div>
これを JavaScript で「その場で作って追加する」のが、
今回の後半のテーマです。
DOM構造として分解してみる
このカードは、DOM的にはこういう構造です。
div(親)
その子どもとして h2
その子どもとして p
つまり、
親となる div を作る
中に入れる h2 を作る
中に入れる p を作る
h2 と p を div に appendChild する
最後に div を画面上のどこかに appendChild する
という「入れ子の appendChild」が必要になります。
カード生成関数を作る
createElement と appendChild の“入れ子”パターン
まずは「タイトルと本文を受け取って、カード要素を返す関数」を作ります。
function createCard(titleText, bodyText) {
const card = document.createElement("div");
card.className = "card";
const title = document.createElement("h2");
title.textContent = titleText;
const body = document.createElement("p");
body.textContent = bodyText;
card.appendChild(title);
card.appendChild(body);
return card;
}
JavaScriptここでやっていることを分解すると、
div を作る(カードの“箱”)
h2 を作って textContent をセット
p を作って textContent をセット
h2 と p を card の子どもとして追加
最後に card 自体を返す
という流れです。
重要なのは、
「appendChild の対象が入れ子になっている」ことです。
card.appendChild(title);
card.appendChild(body);
これで、card の中に h2 と p がぶら下がった
小さな DOM の“島”ができあがります。
作ったカードを画面に追加する
親コンテナに appendChild する
次に、このカードを表示する「置き場」を用意します。
<div id="cardContainer"></div>
JavaScript では、こう使います。
const cardContainer = document.getElementById("cardContainer");
const card1 = createCard("最初のメモ", "これは最初のメモです。");
cardContainer.appendChild(card1);
const card2 = createCard("二つ目のメモ", "これは二つ目のメモです。");
cardContainer.appendChild(card2);
JavaScript流れとしては、
createCard で「完成済みの div(カード)」を作る
cardContainer.appendChild で画面に参加させる
という二段階です。
createElement → appendChild を
「カードの中身を組み立てるため」にも使い、
「カード自体を画面に追加するため」にも使っている、
という二重構造になっています。
ボタンでカードを追加するミニアプリ
完成イメージ
ボタンを押すたびに、
「メモ1」「メモ2」「メモ3」…と
カードが下に増えていく小さなアプリを作ってみます。
HTML 全体
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Day16 DOM操作② 後半</title>
<style>
.card {
border: 1px solid #ccc;
padding: 8px;
margin: 4px 0;
}
</style>
</head>
<body>
<h1>メモカード追加アプリ</h1>
<button id="addButton">メモを追加</button>
<div id="cardContainer"></div>
<script>
const addButtonElement = document.getElementById("addButton");
const cardContainerElement = document.getElementById("cardContainer");
let count = 0;
function createCard(titleText, bodyText) {
const card = document.createElement("div");
card.className = "card";
const title = document.createElement("h2");
title.textContent = titleText;
const body = document.createElement("p");
body.textContent = bodyText;
card.appendChild(title);
card.appendChild(body);
return card;
}
addButtonElement.addEventListener("click", () => {
count += 1;
const card = createCard(
`メモ ${count}`,
`これは ${count} 件目のメモです。`
);
cardContainerElement.appendChild(card);
});
</script>
</body>
</html>
重要なポイントの整理
createCard で「1つのカード」という“まとまり”を作っている
カードの中は、createElement と appendChild の入れ子で構成している
addButton のクリックイベントで、count を増やしつつカードを生成
cardContainer に appendChild して画面に追加している
ここまでできると、
「DOMを1要素ずついじる」のではなく、
「小さなコンポーネントとして組み立てて追加する」
という感覚に一歩踏み込めています。
ユーザー入力を使ったカード生成
入力フォーム付きのカード追加
もう少し実用寄りに、
ユーザーが入力したタイトルと本文でカードを作る例を見ます。
<input id="titleInput" type="text" placeholder="タイトル">
<br>
<textarea id="bodyInput" placeholder="本文"></textarea>
<br>
<button id="addButton">メモを追加</button>
<div id="cardContainer"></div>
JavaScript はこう書けます。
const titleInputElement = document.getElementById("titleInput");
const bodyInputElement = document.getElementById("bodyInput");
const addButtonElement = document.getElementById("addButton");
const cardContainerElement = document.getElementById("cardContainer");
function createCard(titleText, bodyText) {
const card = document.createElement("div");
card.className = "card";
const title = document.createElement("h2");
title.textContent = titleText;
const body = document.createElement("p");
body.textContent = bodyText;
card.appendChild(title);
card.appendChild(body);
return card;
}
addButtonElement.addEventListener("click", () => {
const title = titleInputElement.value;
const body = bodyInputElement.value;
if (title === "" || body === "") {
return;
}
const card = createCard(title, body);
cardContainerElement.appendChild(card);
titleInputElement.value = "";
bodyInputElement.value = "";
});
JavaScriptここでのセキュリティ的に重要なポイントは、
ユーザー入力を textContent に入れていることです。
textContent は「文字として扱う」ため、
ユーザーがどんな文字列を入れても、
それが HTML やスクリプトとして実行されることはありません。
createElement + textContent + appendChild は、
「ユーザー入力を使って DOM を増やすときの安全な基本形」だと覚えておいてください。
ありがちなつまずきと対処
親に appendChild するのを忘れる
createElement で要素を作り、
中身まで設定したのに「画面に出ない」場合、
ほぼ確実に appendChild を忘れています。
チェックポイントはこうです。
どの親要素にぶら下げるのか決めているか
その親要素を getElementById などで取得しているか
最後に appendChild を呼んでいるか
「工場で作った部品を、ちゃんと組み立てラインに乗せたか?」
という視点で見直すと、ミスに気づきやすくなります。
親要素の取得に失敗している
親となるコンテナの id を間違えていると、
cardContainerElement が null になり、
appendChild でエラーになります。
安全に書くなら、こういうチェックも入れられます。
const cardContainerElement = document.getElementById("cardContainer");
if (!cardContainerElement) {
console.error("id=\"cardContainer\" の要素が見つかりません。HTML を確認してください。");
} else {
// ここに appendChild を含む処理を書く
}
JavaScript「想定していた親要素が存在しないときに、そのまま進めない」
というのは、堅牢なコードを書くうえでとても大事です。
Day16 後半のまとめ
createElement は「新しい要素を作る工場」。
appendChild は「作った要素を、どこかの親の子どもとしてDOMツリーに参加させる」操作。
後半では、
複数の要素を組み合わせた「カード」を組み立てる
createElement と appendChild を入れ子にして階層構造を作る
カード生成関数を作って再利用する
ボタンでカードを追加するミニアプリを作る
ユーザー入力を使ってカードを生成する
親要素の取得ミスや appendChild 忘れといった典型的なバグを意識する
ところまで踏み込みました。
ここまで来たあなたは、
「既存のHTMLをいじる人」から、
「JavaScriptでHTMLを“生み出して構成する人”」に確実にステップアップしています。

