4日目のゴールと全体像
サイコロアプリ 4日目のテーマは 「サイコロの結果を“履歴として保存し、一覧表示し、削除できるようにすることで、DOM操作・イベント処理・ローカルストレージの基礎をまとめて体験すること」 です。
ここまでで、みなさんは
- 1つのサイコロの結果表示
- 2つのサイコロの合計値表示
- 合計値に応じた背景色・メッセージ表示
という「動きのあるサイコロアプリ」を作ってきました。
4日目ではここに 履歴機能 を追加して、
- サイコロの結果をオブジェクトとして保存
- 履歴を配列で管理
- ローカルストレージに保存
- 履歴をカードUIとして一覧表示
- 個別削除・全削除
という「データ管理ができるサイコロアプリ」へ進化させます。
履歴機能の設計
まず、どんな履歴を残したいかを決めます。
- サイコロ1の目
- サイコロ2の目
- 合計値
- 振った日時
- 合計値に応じたメッセージ
これらを 1件のオブジェクト として保存します。
履歴1件のデータ構造(オブジェクト)
const historyItem = {
dice1: 4,
dice2: 6,
sum: 10,
dateTime: "2026-08-06 14:20",
message: "最高の運勢!何をしても楽しめそうです!"
};
JavaScript履歴全体(配列)
const historyArray = [
{ dice1: 3, dice2: 2, sum: 5, dateTime: "...", message: "..." },
{ dice1: 6, dice2: 6, sum: 12, dateTime: "...", message: "..." }
];
JavaScriptこの「配列+オブジェクト」の組み合わせは、 Webアプリでデータを扱うときの基本パターン です。
HTMLに履歴表示エリアを追加する
<h3>履歴</h3>
<div id="historyList"></div>
<button id="clearHistoryBtn">履歴をすべて削除</button>
深掘りポイント
id="historyList"に JavaScriptからカードを追加していくid="clearHistoryBtn"で全削除機能を作る- DOM操作は「HTML側に置き場所を作る → JSで中身を入れる」が基本
CSSで履歴カードを整える
.history-card {
background: #fff;
padding: 12px;
margin: 10px 0;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.history-card p {
margin: 4px 0;
}
.history-delete-btn {
margin-top: 6px;
padding: 6px 10px;
cursor: pointer;
font-size: 12px;
}
ローカルストレージで履歴を保存・読み込みする
ローカルストレージとは
ブラウザにデータを保存しておける仕組みです。 ページを閉じてもデータが残ります。
- 保存:
localStorage.setItem("キー", "文字列") - 読み込み:
localStorage.getItem("キー")
配列やオブジェクトはそのまま保存できないため、 JSON文字列に変換して保存 します。
履歴配列の宣言と読み込み
let historyArray = loadHistory();
function loadHistory() {
const data = localStorage.getItem("diceHistory");
return data ? JSON.parse(data) : [];
}
JavaScript履歴を保存する関数
function saveHistory(arr) {
localStorage.setItem("diceHistory", JSON.stringify(arr));
}
JavaScript履歴を追加する処理
サイコロを振ったときに履歴を追加します。
rollBtn.addEventListener("click", function() {
const n1 = rollDice();
const n2 = rollDice();
const sum = n1 + n2;
dice1.textContent = `サイコロ1:${n1}`;
dice2.textContent = `サイコロ2:${n2}`;
diceSum.textContent = `合計:${sum}`;
updateBackground(sum);
const msg = getSumMessage(sum);
diceMessage.textContent = msg;
const now = new Date();
const dateTimeText = `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()} ${now.getHours()}:${now.getMinutes()}`;
const historyItem = {
dice1: n1,
dice2: n2,
sum: sum,
dateTime: dateTimeText,
message: msg
};
historyArray.push(historyItem);
saveHistory(historyArray);
renderHistory(historyArray);
});
JavaScript深掘りポイント
- 「データを作る → 配列に追加 → 保存 → 画面更新」 この流れはどんなアプリでも共通
- 履歴は「オブジェクト」でまとめると扱いやすい
履歴を画面に表示する(DOM操作)
function renderHistory(historyArray) {
const list = document.getElementById("historyList");
list.innerHTML = "";
historyArray.forEach((item, index) => {
const card = document.createElement("div");
card.className = "history-card";
card.innerHTML = `
<p>日時:${item.dateTime}</p>
<p>サイコロ1:${item.dice1}</p>
<p>サイコロ2:${item.dice2}</p>
<p>合計:${item.sum}</p>
<p>メッセージ:${item.message}</p>
<button class="history-delete-btn">削除</button>
`;
const deleteBtn = card.querySelector(".history-delete-btn");
deleteBtn.addEventListener("click", function() {
deleteHistory(index);
});
list.appendChild(card);
});
}
JavaScript深掘りポイント
.innerHTML = ""で一度全消し → 再描画.forEach()で配列の各要素をカード化createElement()とappendChild()が DOM操作の基本
履歴を削除する処理
個別削除
function deleteHistory(index) {
historyArray.splice(index, 1);
saveHistory(historyArray);
renderHistory(historyArray);
}
JavaScript全削除
clearHistoryBtn.addEventListener("click", function() {
localStorage.removeItem("diceHistory");
historyArray = [];
renderHistory(historyArray);
});
JavaScript4日目の完成コード(script.js 全体)
const rollBtn = document.getElementById("rollBtn");
const dice1 = document.getElementById("dice1");
const dice2 = document.getElementById("dice2");
const diceSum = document.getElementById("diceSum");
const diceMessage = document.getElementById("diceMessage");
const clearHistoryBtn = document.getElementById("clearHistoryBtn");
let historyArray = loadHistory();
function rollDice() {
return Math.floor(Math.random() * 6) + 1;
}
function updateBackground(sum) {
if (sum <= 4) document.body.style.backgroundColor = "#f8d7da";
else if (sum <= 8) document.body.style.backgroundColor = "#cce5ff";
else document.body.style.backgroundColor = "#fff8b3";
}
function getSumMessage(sum) {
if (sum <= 4) return "今日は慎重にいきましょう。";
if (sum <= 8) return "まずまずの運勢。落ち着いて進めればOK。";
return "最高の運勢!何をしても楽しめそうです!";
}
function saveHistory(arr) {
localStorage.setItem("diceHistory", JSON.stringify(arr));
}
function loadHistory() {
const data = localStorage.getItem("diceHistory");
return data ? JSON.parse(data) : [];
}
function deleteHistory(index) {
historyArray.splice(index, 1);
saveHistory(historyArray);
renderHistory(historyArray);
}
function renderHistory(historyArray) {
const list = document.getElementById("historyList");
list.innerHTML = "";
historyArray.forEach((item, index) => {
const card = document.createElement("div");
card.className = "history-card";
card.innerHTML = `
<p>日時:${item.dateTime}</p>
<p>サイコロ1:${item.dice1}</p>
<p>サイコロ2:${item.dice2}</p>
<p>合計:${item.sum}</p>
<p>メッセージ:${item.message}</p>
<button class="history-delete-btn">削除</button>
`;
card.querySelector(".history-delete-btn").addEventListener("click", function() {
deleteHistory(index);
});
list.appendChild(card);
});
}
rollBtn.addEventListener("click", function() {
const n1 = rollDice();
const n2 = rollDice();
const sum = n1 + n2;
dice1.textContent = `サイコロ1:${n1}`;
dice2.textContent = `サイコロ2:${n2}`;
diceSum.textContent = `合計:${sum}`;
updateBackground(sum);
const msg = getSumMessage(sum);
diceMessage.textContent = msg;
const now = new Date();
const dateTimeText = `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()} ${now.getHours()}:${now.getMinutes()}`;
const historyItem = {
dice1: n1,
dice2: n2,
sum: sum,
dateTime: dateTimeText,
message: msg
};
historyArray.push(historyItem);
saveHistory(historyArray);
renderHistory(historyArray);
});
clearHistoryBtn.addEventListener("click", function() {
localStorage.removeItem("diceHistory");
historyArray = [];
renderHistory(historyArray);
});
renderHistory(historyArray);
JavaScript4日目で本当に掴んでほしいこと
● ローカルストレージは「ブラウザに保存できる小さなデータベース」
- 配列を JSON にして保存
- JSON を配列に戻して読み込み
- ページを閉じてもデータが残る
● DOM操作で「一覧表示」を作れるようになる
createElement()appendChild()innerHTML
これらを組み合わせると、 どんなデータでもカードUIにできる。
● イベント処理は「ユーザーの操作に反応する」
- ボタンを押す → 履歴追加
- 削除ボタン → 履歴削除
- 全削除ボタン → 履歴リセット
次のステップ(5日目)
5日目ではさらに一歩進んで、
- 履歴の並び替え(新しい順・古い順)
- 履歴の詳細表示
- カードの色分け・アニメーション削除
という「本格的なサイコロアプリ」へ育てていきます。


