JavaScript | ゼロからはじめるプログラミング、30日で基礎を学ぶJavaScript:Webページを操作できるようになる - Day23:総合演習②

JavaScript JavaScript
スポンサーリンク

Day23 後半のゴール

前半で「入力 → 追加 → 画面に表示」までの簡易メモ帳ができました。
後半では、ここに

localStorage を使ったメモの保存
ページ読み込み時のメモ復元
配列+関数分割での整理

を加えて、「リロードしても消えないメモ帳」に育てていきます。
ここまでできると、もう立派なミニ Web アプリです。


メモを配列で管理する設計に変える

なぜ配列が必要になるのか

前半のコードでは、メモを追加するときに

テキストを受け取る
p 要素を作る
その場で appendChild する

という「一発勝負」の処理をしていました。
しかし、localStorage に保存したいのは「画面」ではなく「データ」です。
つまり、「メモの一覧」を JavaScript の中で持っておく必要があります。

そこで登場するのが配列です。
メモを 1 件ずつ文字列として配列に入れておき、
画面には「配列の中身をもとに描画する」という形に変えていきます。

メモ配列と描画関数を用意する

まず、メモを入れておく配列と、
その配列から画面を描画する関数を作ります。

const memoInputElement = document.getElementById("memoInput");
const addButtonElement = document.getElementById("addButton");
const memoListElement = document.getElementById("memoList");

let memos = [];

function renderMemos() {
  memoListElement.textContent = "";

  memos.forEach((text) => {
    const memoElement = document.createElement("p");
    memoElement.textContent = text;
    memoListElement.appendChild(memoElement);
  });
}
JavaScript

ここでのポイントは、

memos という配列が「メモの真の姿」
画面はいつでも renderMemos を呼べば再描画できる

という構造にしていることです。
この形にしておくと、「保存」「読み込み」との相性がとても良くなります。


追加処理を「配列+描画」に書き換える

配列に push してから描画する流れ

前半では、ボタンを押したときに直接 p 要素を作っていました。
後半では、「配列を更新 → 画面を再描画」という流れに変えます。

addButtonElement.addEventListener("click", () => {
  const text = memoInputElement.value.trim();

  if (text === "") {
    return;
  }

  memos.push(text);

  renderMemos();

  memoInputElement.value = "";
});
JavaScript

これで、

memos 配列にメモが溜まっていく
画面は常に memos の内容を反映している

という状態になります。
この「配列が真実、画面はその写し」という考え方は、
今後もっと大きなアプリを書くときにもずっと使います。


localStorage にメモ一覧を保存する

配列はそのままでは保存できない

localStorage は「文字列しか保存できない」ので、
配列をそのまま保存することはできません。
そこで使うのが JSON です。

配列 → JSON 文字列に変換:JSON.stringify
JSON 文字列 → 配列に戻す:JSON.parse

この 2 つを組み合わせて、memos を保存・復元します。

保存用の関数を作る

まずは「今の memos を localStorage に保存する」関数を作ります。

function saveMemos() {
  const json = JSON.stringify(memos);
  localStorage.setItem("memos", json);
}
JavaScript

これを、メモを追加したタイミングで呼びます。

addButtonElement.addEventListener("click", () => {
  const text = memoInputElement.value.trim();

  if (text === "") {
    return;
  }

  memos.push(text);

  saveMemos();
  renderMemos();

  memoInputElement.value = "";
});
JavaScript

ここでの流れは、

配列を更新する
保存する
画面を描画する

という順番です。
「配列が真実 → それを保存 → それを表示」という筋が通っています。


ページ読み込み時にメモを復元する

localStorage から配列を読み込む

次に、「ページを開いたときに前回のメモを復元する」処理を書きます。
これも関数にしておくと分かりやすいです。

function loadMemos() {
  const json = localStorage.getItem("memos");
  if (json === null) {
    memos = [];
    return;
  }

  memos = JSON.parse(json);
}
JavaScript

そして、スクリプトの最後で

loadMemos();
renderMemos();

と呼びます。

loadMemos();
renderMemos();
JavaScript

これで、

ページを開く
localStorage から memos を読み込む
読み込んだ配列をもとに画面を描画する

という流れが完成します。


全体コードを整理して眺める

関数ごとの役割を意識する

ここまでの内容をまとめたコードがこちらです。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>簡易メモ帳</title>
  </head>
  <body>
    <h1>簡易メモ帳</h1>

    <h2>新しいメモ</h2>
    <textarea id="memoInput" rows="4" cols="40" placeholder="ここにメモを書いてください"></textarea>
    <p>
      <button id="addButton">追加</button>
    </p>

    <h2>メモ一覧</h2>
    <div id="memoList"></div>

    <script>
      const memoInputElement = document.getElementById("memoInput");
      const addButtonElement = document.getElementById("addButton");
      const memoListElement = document.getElementById("memoList");

      let memos = [];

      function renderMemos() {
        memoListElement.textContent = "";

        memos.forEach((text) => {
          const memoElement = document.createElement("p");
          memoElement.textContent = text;
          memoListElement.appendChild(memoElement);
        });
      }

      function saveMemos() {
        const json = JSON.stringify(memos);
        localStorage.setItem("memos", json);
      }

      function loadMemos() {
        const json = localStorage.getItem("memos");
        if (json === null) {
          memos = [];
          return;
        }
        memos = JSON.parse(json);
      }

      addButtonElement.addEventListener("click", () => {
        const text = memoInputElement.value.trim();

        if (text === "") {
          return;
        }

        memos.push(text);
        saveMemos();
        renderMemos();
        memoInputElement.value = "";
      });

      loadMemos();
      renderMemos();
    </script>
  </body>
</html>

関数ごとの役割を整理すると、こうなります。

renderMemos
memos 配列の内容を画面に反映する

saveMemos
memos 配列を JSON にして localStorage に保存する

loadMemos
localStorage から JSON を読み込み、memos 配列に戻す

イベントハンドラ
入力値を取得・チェックする
memos に追加する
保存して描画する

「誰が何を担当しているか」がはっきり分かれているのが分かると思います。


デバッグの視点をもう一度入れてみる

保存・読み込みがうまくいかないときの確認ポイント

もし「メモが保存されない」「復元されない」と感じたら、
次のように console.log を仕込んでみてください。

function saveMemos() {
  const json = JSON.stringify(memos);
  console.log("保存する JSON:", json);
  localStorage.setItem("memos", json);
}

function loadMemos() {
  const json = localStorage.getItem("memos");
  console.log("読み込んだ JSON:", json);
  if (json === null) {
    memos = [];
    return;
  }
  memos = JSON.parse(json);
  console.log("復元した memos:", memos);
}
JavaScript

これで、

そもそも saveMemos が呼ばれているか
localStorage にどんな文字列が入っているか
JSON.parse 後の配列がどうなっているか

を一つずつ確認できます。
Day22 で学んだ「console.log で事実を見る」を、
総合演習でもそのまま使っていくイメージです。


Day23 後半のまとめ

後半でやったことを整理すると、こうなります。

メモを配列(memos)で管理するようにした
配列から画面を描画する renderMemos を作った
memos を JSON にして localStorage に保存する saveMemos を作った
localStorage から JSON を読み込んで配列に戻す loadMemos を作った
ページ読み込み時に loadMemos → renderMemos を呼ぶようにした

これで、「リロードしてもメモが残る簡易メモ帳」が完成しました。
ここまで来ると、もう立派に「自分の道具」を JavaScript で作れている状態です。

このメモ帳をベースに、

削除ボタンを付ける
1 件ずつ消せるようにする
日時を一緒に保存する

といった拡張も、今のあなたなら十分狙えます。
やってみたくなったら、そこからがもう「自分の作品づくり」の時間です。

タイトルとURLをコピーしました