基礎から学ぶJavaScript入門 90日コース | Webページを操作するDOM - Day 44:DOM総復習

JavaScript 90日で身につけるJavaScript
スポンサーリンク
スポンサーリンク
  1. Day 44:DOM総復習(前半)
  2. 総復習で作るミニアプリのイメージ
    1. 「メモを追加・強調・削除できる」小さなアプリ
  3. HTMLでミニアプリの土台を作る
    1. 入力欄・追加ボタン・メモリストを用意する
  4. 要素取得:DOM操作の入口をしっかり押さえる
    1. getElementByIdで必要な要素を変数にまとめる
  5. イベント:ユーザーの操作に反応する
    1. 「追加」ボタンのクリックイベントを設定する
  6. テキスト変更:入力値を読み取り、表示に反映する
    1. 入力欄の値を取得する
  7. 要素追加:新しいメモ要素を作ってリストに追加する
    1. createElementでliと削除ボタンを作る
  8. クラス操作:見た目の状態を切り替える
    1. メモをクリックしたら「重要」クラスを付ける
  9. 要素削除:削除ボタンでメモを消す
    1. remove() でli要素を削除する
  10. ここまでをまとめた完成コード(総復習版メモアプリ)
  11. 練習用テンプレート:自分で書き換えながら復習する
  12. Day 44 前半のまとめ
  13. Day 44:DOM総復習(後半)
  14. 追加する機能の全体像を整理する
    1. どんな振る舞いを足すと“アプリらしく”なるか
  15. HTMLに新しい操作ボタンと件数表示を追加する
    1. 件数表示・すべて削除・重要強調ボタンを用意する
  16. 要素取得:新しいボタンと件数表示も変数にまとめる
    1. すべての操作対象を最初に取得しておく
  17. テキスト変更:メモ件数を常に最新に保つ
    1. 件数を数えて表示する関数を作る
  18. 要素追加+イベント+クラス操作:メモ追加処理を整理する
    1. 1件分のメモ要素を作る関数を用意する
  19. メモ追加のイベント処理をシンプルにする
    1. 入力チェック → 要素追加 → 件数更新
  20. イベントの応用:Enterキーでメモを追加する
    1. キーボード操作にも反応させる
  21. 要素削除の応用:「すべて削除」ボタン
    1. 子要素をまとめて削除する
  22. クラス操作の応用:「重要メモを強調」ボタン
    1. 重要メモだけに追加のクラスを付ける
  23. 完成コード(総復習+拡張版メモアプリ)
  24. 練習用テンプレート:自分で機能を足してみるためのベース
  25. Day 44 後半のまとめ

Day 44:DOM総復習(前半)

「DOM操作の“基本6セット”を1つのミニアプリでつなげて理解する」

Day 44前半では、これまで学んできたDOM操作を総復習します。 テーマは次の6つです。

  • 要素取得
  • テキスト変更
  • クラス操作
  • イベント
  • 要素追加
  • 要素削除

これらは、ほぼすべてのWebアプリで使われる DOM操作の基本セット です。 今回は、シンプルな「メモリストアプリ」を題材にして、 6つの要素を 1つの流れの中で使えるようになること を目指します。

総復習で作るミニアプリのイメージ

「メモを追加・強調・削除できる」小さなアプリ

今回のミニアプリは、次のような機能を持たせます。

  • テキスト入力欄にメモを入力する
  • 「追加」ボタンでメモをリストに追加する
  • メモをクリックすると「重要」クラスが付いて見た目が変わる
  • メモの右側に「削除」ボタンを付けて、クリックで削除できる

このアプリの中で、

  • 要素取得
  • テキスト変更
  • クラス操作
  • イベント
  • 要素追加
  • 要素削除

をすべて使っていきます。

HTMLでミニアプリの土台を作る

入力欄・追加ボタン・メモリストを用意する

まずは、アプリのUIとなるHTMLを用意します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Day 44 前半:DOM総復習 メモアプリ</title>
  <style>
    body {
      font-family: sans-serif;
      padding: 20px;
    }

    #memoInput {
      width: 240px;
      padding: 6px;
    }

    #addButton {
      padding: 6px 12px;
      margin-left: 4px;
      cursor: pointer;
    }

    #memoList {
      margin-top: 16px;
      padding-left: 0;
      list-style: none;
    }

    /* ▼ メモ1件分のスタイル */
    .memo-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 6px 8px;
      margin-bottom: 4px;
      border: 1px solid #ccc;
      border-radius: 4px;
    }

    /* ▼ 重要メモの強調表示用クラス */
    .important {
      background-color: #fff3cd;
      border-color: #ffecb5;
      font-weight: bold;
    }

    .delete-button {
      padding: 2px 8px;
      font-size: 0.8rem;
      cursor: pointer;
      color: #fff;
      background-color: #dc3545;
      border: none;
      border-radius: 4px;
    }
  </style>
</head>
<body>
  <h1>DOM総復習:メモリストアプリ</h1>

  <!-- ▼ メモ入力欄 -->
  <input id="memoInput" type="text" placeholder="メモを入力してください">

  <!-- ▼ メモ追加ボタン -->
  <button id="addButton">追加</button>

  <!-- ▼ メモリスト表示エリア -->
  <ul id="memoList"></ul>

  <script>
    // ここにJavaScriptを書いていきます
  </script>
</body>
</html>

ここでのポイントは、

  • 入力欄に id="memoInput"、追加ボタンに id="addButton"、リストに id="memoList" を付けていること
  • メモ1件分の見た目を .memo-item クラスで定義していること
  • 重要メモ用の .important クラスを用意していること

です。

要素取得:DOM操作の入口をしっかり押さえる

getElementByIdで必要な要素を変数にまとめる

DOM操作の第一歩は 要素取得 です。 JavaScriptからHTMLの要素を操作するには、まず「どの要素か」を特定する必要があります。

// ▼ メモ入力欄の要素を取得します
const memoInputElement = document.getElementById('memoInput');

// ▼ メモ追加ボタンの要素を取得します
const addButtonElement = document.getElementById('addButton');

// ▼ メモリスト(ul)の要素を取得します
const memoListElement = document.getElementById('memoList');
JavaScript

ここでの重要ポイントは、

  • id を付けておくと getElementById() で簡単に取得できること
  • 取得した要素を変数に入れておくことで、後の処理が読みやすくなること

です。

イベント:ユーザーの操作に反応する

「追加」ボタンのクリックイベントを設定する

次に、ユーザーの操作に反応するために イベント を設定します。

// ▼ 「追加」ボタンがクリックされたときの処理を登録します
addButtonElement.addEventListener('click', function () {
  // ここにメモ追加の処理を書いていきます
});
JavaScript

イベントの基本は、

  • 「どの要素に対して」
  • 「どのイベント(click, input, changeなど)で」
  • 「どんな処理を実行するか」

をセットで考えることです。

テキスト変更:入力値を読み取り、表示に反映する

入力欄の値を取得する

メモ追加の処理では、まず入力欄のテキストを取得します。

addButtonElement.addEventListener('click', function () {
  // ▼ 入力欄の値(文字列)を取得します
  const memoText = memoInputElement.value;

  // ▼ 空文字の場合は何もしないようにします
  if (memoText.trim() === '') {
    alert('メモを入力してください。');
    return;
  }

  // このあと要素追加の処理に進みます
});
JavaScript

ここでのポイントは、

  • value プロパティで入力欄のテキストを取得できること
  • trim() で前後の空白を取り除いてから空チェックしていること
  • 空入力のときに alert でユーザーに知らせていること

です。

要素追加:新しいメモ要素を作ってリストに追加する

createElementでliと削除ボタンを作る

メモ1件分の要素を、JavaScriptで動的に作成します。

addButtonElement.addEventListener('click', function () {
  const memoText = memoInputElement.value;

  if (memoText.trim() === '') {
    alert('メモを入力してください。');
    return;
  }

  // ▼ li要素(メモ1件分)を作成します
  const memoItemElement = document.createElement('li');
  memoItemElement.classList.add('memo-item'); // 見た目用のクラスを付けます

  // ▼ メモ本文を表示するためのspan要素を作成します
  const memoTextElement = document.createElement('span');
  memoTextElement.textContent = memoText; // テキストを設定します

  // ▼ 削除ボタンを作成します
  const deleteButtonElement = document.createElement('button');
  deleteButtonElement.textContent = '削除';
  deleteButtonElement.classList.add('delete-button');

  // ▼ liの中にspanと削除ボタンを追加します
  memoItemElement.appendChild(memoTextElement);
  memoItemElement.appendChild(deleteButtonElement);

  // ▼ 完成したli要素をul(memoList)に追加します
  memoListElement.appendChild(memoItemElement);

  // ▼ 入力欄を空にしておきます
  memoInputElement.value = '';
});
JavaScript

ここでの重要ポイントは、

  • document.createElement('li') で新しい要素を作っていること
  • textContent でテキストを設定していること
    • innerHTML ではなく textContent を使うことで、 ユーザー入力を安全にテキストとして扱えること
  • appendChild() で親要素に子要素を追加していること

です。

クラス操作:見た目の状態を切り替える

メモをクリックしたら「重要」クラスを付ける

次に、メモをクリックしたときに見た目を変えるため、 クラス操作 を使います。

// ▼ メモ本文(span)をクリックしたときに「重要」クラスを切り替えます
  memoTextElement.addEventListener('click', function () {
    // memoItemElementに対してimportantクラスを付けたり外したりします
    memoItemElement.classList.toggle('important');
  });
JavaScript

ここでのポイントは、

  • classList.toggle('important') で、 クラスが付いていなければ付け、付いていれば外すという切り替えができること
  • 見た目の状態(重要かどうか)を クラスで表現する ことで、 CSSとJavaScriptの役割分担が明確になること

です。

要素削除:削除ボタンでメモを消す

remove() でli要素を削除する

削除ボタンがクリックされたときに、 そのメモ(li要素)を削除します。

// ▼ 削除ボタンがクリックされたときに、このメモを削除します
  deleteButtonElement.addEventListener('click', function () {
    // memoItemElement(li)をDOMツリーから削除します
    memoItemElement.remove();
  });
JavaScript

ここでの重要ポイントは、

  • remove() メソッドで、要素自身をDOMから取り除けること
  • 「どの要素を削除するか」を明確にするために、 削除ボタンのイベント内で memoItemElement を参照していること

です。

ここまでをまとめた完成コード(総復習版メモアプリ)

HTMLとJavaScriptを合わせた完成コードです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Day 44 前半:DOM総復習 メモアプリ</title>
  <style>
    body {
      font-family: sans-serif;
      padding: 20px;
    }

    #memoInput {
      width: 240px;
      padding: 6px;
    }

    #addButton {
      padding: 6px 12px;
      margin-left: 4px;
      cursor: pointer;
    }

    #memoList {
      margin-top: 16px;
      padding-left: 0;
      list-style: none;
    }

    .memo-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 6px 8px;
      margin-bottom: 4px;
      border: 1px solid #ccc;
      border-radius: 4px;
    }

    .important {
      background-color: #fff3cd;
      border-color: #ffecb5;
      font-weight: bold;
    }

    .delete-button {
      padding: 2px 8px;
      font-size: 0.8rem;
      cursor: pointer;
      color: #fff;
      background-color: #dc3545;
      border: none;
      border-radius: 4px;
    }
  </style>
</head>
<body>
  <h1>DOM総復習:メモリストアプリ</h1>

  <input id="memoInput" type="text" placeholder="メモを入力してください">
  <button id="addButton">追加</button>

  <ul id="memoList"></ul>

  <script>
    // ▼ 要素取得
    const memoInputElement = document.getElementById('memoInput');
    const addButtonElement = document.getElementById('addButton');
    const memoListElement = document.getElementById('memoList');

    // ▼ 「追加」ボタンのクリックイベント
    addButtonElement.addEventListener('click', function () {
      const memoText = memoInputElement.value;

      // 空入力のチェック
      if (memoText.trim() === '') {
        alert('メモを入力してください。');
        return;
      }

      // ▼ li要素(メモ1件分)を作成
      const memoItemElement = document.createElement('li');
      memoItemElement.classList.add('memo-item');

      // ▼ メモ本文用のspan要素を作成
      const memoTextElement = document.createElement('span');
      memoTextElement.textContent = memoText; // テキスト変更

      // ▼ 削除ボタンを作成
      const deleteButtonElement = document.createElement('button');
      deleteButtonElement.textContent = '削除';
      deleteButtonElement.classList.add('delete-button');

      // ▼ liの中にspanと削除ボタンを追加(要素追加)
      memoItemElement.appendChild(memoTextElement);
      memoItemElement.appendChild(deleteButtonElement);

      // ▼ ulにliを追加(要素追加)
      memoListElement.appendChild(memoItemElement);

      // ▼ 入力欄を空にする(テキスト変更)
      memoInputElement.value = '';

      // ▼ メモ本文クリックで「重要」クラスを切り替え(クラス操作+イベント)
      memoTextElement.addEventListener('click', function () {
        memoItemElement.classList.toggle('important');
      });

      // ▼ 削除ボタンクリックでこのメモを削除(要素削除+イベント)
      deleteButtonElement.addEventListener('click', function () {
        memoItemElement.remove();
      });
    });
  </script>
</body>
</html>

このコードの中に、 Day 44前半の復習テーマがすべて入っています。

  • 要素取得getElementById
  • テキスト変更valuetextContent
  • クラス操作classList.add / classList.toggle
  • イベントaddEventListener('click', ...)
  • 要素追加createElement + appendChild
  • 要素削除remove()

練習用テンプレート:自分で書き換えながら復習する

最後に、少し簡略化した練習用テンプレートを紹介します。 コメントを見ながら、自分で書き換えて試してみるのに向いています。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Day 44 前半:DOM総復習 テンプレート</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    #memoList { margin-top: 16px; padding-left: 0; list-style: none; }
    .memo-item { display: flex; justify-content: space-between; padding: 6px 8px; border: 1px solid #ccc; margin-bottom: 4px; }
    .important { background-color: #fff3cd; font-weight: bold; }
    .delete-button { padding: 2px 8px; font-size: 0.8rem; cursor: pointer; }
  </style>
</head>
<body>
  <h1>DOM総復習 テンプレート</h1>

  <input id="memoInput" type="text" placeholder="メモ">
  <button id="addButton">追加</button>

  <ul id="memoList"></ul>

  <script>
    console.log('--- DOM総復習開始 ---');

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

    addButtonElement.addEventListener('click', () => {
      const memoText = memoInputElement.value;

      if (memoText.trim() === '') {
        alert('メモを入力してください。');
        return;
      }

      const memoItemElement = document.createElement('li');
      memoItemElement.classList.add('memo-item');

      const memoTextElement = document.createElement('span');
      memoTextElement.textContent = memoText;

      const deleteButtonElement = document.createElement('button');
      deleteButtonElement.textContent = '削除';
      deleteButtonElement.classList.add('delete-button');

      memoItemElement.appendChild(memoTextElement);
      memoItemElement.appendChild(deleteButtonElement);
      memoListElement.appendChild(memoItemElement);

      memoInputElement.value = '';

      memoTextElement.addEventListener('click', () => {
        memoItemElement.classList.toggle('important');
      });

      deleteButtonElement.addEventListener('click', () => {
        memoItemElement.remove();
      });
    });

    console.log('--- DOM総復習テンプレートの準備が完了しました ---');
  </script>
</body>
</html>

Day 44 前半のまとめ

Day 44前半では、 1つのメモリストアプリの中で、

  • 要素取得
  • テキスト変更
  • クラス操作
  • イベント
  • 要素追加
  • 要素削除

という、DOM操作の基本6セットを ひとつながりの流れとして復習 しました。

ここまでできると、 「ユーザーの入力を受け取り、画面に要素を追加し、状態を変え、必要になったら削除する」 という、Webアプリの基本パターンを自分の手で組み立てられるようになります。


Day 44:DOM総復習(後半)

「“少しだけ複雑な振る舞い”を足して、DOM操作の基本6セットを体に染み込ませる」

Day 44後半では、前半で作成したメモリストアプリを少し発展させて、 「複数のDOM操作を組み合わせて、状態を管理する感覚」 を身につけていきます。

復習テーマは同じく、

  • 要素取得
  • テキスト変更
  • クラス操作
  • イベント
  • 要素追加
  • 要素削除

ですが、後半では次のような機能を追加していきます。

  • メモ件数の表示(テキスト変更の応用)
  • 「すべて削除」ボタン(要素削除の応用)
  • 「重要メモだけを強調」するクラス操作
  • Enterキーでメモ追加(イベントの応用)

前半で学んだことを、 「少しだけ現実的なアプリ」に近づける形で総復習していきます。

追加する機能の全体像を整理する

どんな振る舞いを足すと“アプリらしく”なるか

前半のメモアプリは、次の機能を持っていました。

  • メモを入力して「追加」ボタンでリストに追加
  • メモ本文をクリックすると「重要」クラスが付く/外れる
  • 削除ボタンでメモを削除

後半では、これに次の機能を足します。

  • メモの件数を画面に表示する(例:「メモ件数:3件」)
  • 「すべて削除」ボタンで、全メモを一気に削除する
  • 「重要メモを強調」ボタンで、重要メモだけを目立たせる
  • Enterキーでメモを追加できるようにする

これらはすべて、 DOM操作の基本6セットの組み合わせ で実現できます。

HTMLに新しい操作ボタンと件数表示を追加する

件数表示・すべて削除・重要強調ボタンを用意する

前半のHTMLに、次の要素を追加します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Day 44 後半:DOM総復習 メモアプリ拡張</title>
  <style>
    body {
      font-family: sans-serif;
      padding: 20px;
    }

    #memoInput {
      width: 240px;
      padding: 6px;
    }

    #addButton,
    #clearAllButton,
    #highlightImportantButton {
      padding: 6px 12px;
      margin-left: 4px;
      cursor: pointer;
    }

    #memoList {
      margin-top: 16px;
      padding-left: 0;
      list-style: none;
    }

    .memo-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 6px 8px;
      margin-bottom: 4px;
      border: 1px solid #ccc;
      border-radius: 4px;
    }

    .important {
      background-color: #fff3cd;
      border-color: #ffecb5;
      font-weight: bold;
    }

    .delete-button {
      padding: 2px 8px;
      font-size: 0.8rem;
      cursor: pointer;
      color: #fff;
      background-color: #dc3545;
      border: none;
      border-radius: 4px;
    }

    /* ▼ 件数表示用 */
    #memoCount {
      margin-top: 12px;
      font-size: 0.9rem;
      color: #555;
    }
  </style>
</head>
<body>
  <h1>DOM総復習:メモリストアプリ拡張</h1>

  <!-- ▼ メモ入力欄 -->
  <input id="memoInput" type="text" placeholder="メモを入力してください">

  <!-- ▼ メモ追加ボタン -->
  <button id="addButton">追加</button>

  <!-- ▼ すべて削除ボタン -->
  <button id="clearAllButton">すべて削除</button>

  <!-- ▼ 重要メモ強調ボタン -->
  <button id="highlightImportantButton">重要メモを強調</button>

  <!-- ▼ メモ件数表示 -->
  <p id="memoCount">メモ件数:0件</p>

  <!-- ▼ メモリスト表示エリア -->
  <ul id="memoList"></ul>

  <script>
    // ここにJavaScriptを書いていきます
  </script>
</body>
</html>

ここでのポイントは、

  • clearAllButtonhighlightImportantButton を追加していること
  • memoCount という件数表示用の要素を用意していること
  • ボタンのスタイルをまとめて指定して、見た目を揃えていること

です。

要素取得:新しいボタンと件数表示も変数にまとめる

すべての操作対象を最初に取得しておく

// ▼ メモ入力欄
const memoInputElement = document.getElementById('memoInput');

// ▼ メモ追加ボタン
const addButtonElement = document.getElementById('addButton');

// ▼ すべて削除ボタン
const clearAllButtonElement = document.getElementById('clearAllButton');

// ▼ 重要メモ強調ボタン
const highlightImportantButtonElement = document.getElementById('highlightImportantButton');

// ▼ メモリスト(ul)
const memoListElement = document.getElementById('memoList');

// ▼ メモ件数表示
const memoCountElement = document.getElementById('memoCount');
JavaScript

ここでの重要ポイントは、

  • 「後で何度も使う要素」は、最初にまとめて取得しておくとコードが読みやすくなること
  • 変数名を「何の要素か」が分かるように付けることで、 自分や他の人が後から読んだときに理解しやすくなること

です。

テキスト変更:メモ件数を常に最新に保つ

件数を数えて表示する関数を作る

メモを追加・削除するたびに、 件数表示を更新する必要があります。

// ▼ メモ件数を数えて表示を更新する関数
function updateMemoCount() {
  // memoList内のli要素の数を数えます
  const memoItems = memoListElement.querySelectorAll('li');
  const count = memoItems.length;

  // 件数表示を更新します(テキスト変更)
  memoCountElement.textContent = `メモ件数:${count}件`;
}
JavaScript

ここでのポイントは、

  • querySelectorAll('li') で、memoList 内のすべてのメモ要素を取得していること
  • length で件数を数え、textContent で表示を更新していること
  • 件数表示の更新を 1つの関数にまとめている ので、 「追加」「削除」「すべて削除」など、どこからでも呼び出せること

です。

要素追加+イベント+クラス操作:メモ追加処理を整理する

1件分のメモ要素を作る関数を用意する

前半では、追加ボタンのイベントの中にすべての処理を書いていましたが、 後半では 「メモ1件分を作る関数」 に切り出して整理します。

// ▼ メモ1件分の要素を作成して、イベントも設定する関数
function createMemoItem(memoText) {
  // li要素を作成
  const memoItemElement = document.createElement('li');
  memoItemElement.classList.add('memo-item');

  // メモ本文用のspan要素
  const memoTextElement = document.createElement('span');
  memoTextElement.textContent = memoText;

  // 削除ボタン
  const deleteButtonElement = document.createElement('button');
  deleteButtonElement.textContent = '削除';
  deleteButtonElement.classList.add('delete-button');

  // liの中にspanと削除ボタンを追加
  memoItemElement.appendChild(memoTextElement);
  memoItemElement.appendChild(deleteButtonElement);

  // ▼ メモ本文クリックで「重要」クラスを切り替え(クラス操作+イベント)
  memoTextElement.addEventListener('click', function () {
    memoItemElement.classList.toggle('important');
  });

  // ▼ 削除ボタンクリックでこのメモを削除(要素削除+イベント)
  deleteButtonElement.addEventListener('click', function () {
    memoItemElement.remove();
    updateMemoCount(); // 削除後に件数を更新します
  });

  return memoItemElement;
}
JavaScript

ここでの重要ポイントは、

  • 「メモ1件分の作成+イベント設定」を1つの関数にまとめていること
  • createMemoItem() が「li要素を返す」関数になっているので、 呼び出し側で appendChild() するだけでよいこと
  • 削除時に updateMemoCount() を呼び出して、 件数表示を常に最新に保っていること

です。

メモ追加のイベント処理をシンプルにする

入力チェック → 要素追加 → 件数更新

createMemoItem() を使うことで、 追加ボタンのイベント処理をシンプルに書けます。

// ▼ 「追加」ボタンのクリックイベント
addButtonElement.addEventListener('click', function () {
  const memoText = memoInputElement.value;

  // 空入力のチェック
  if (memoText.trim() === '') {
    alert('メモを入力してください。');
    return;
  }

  // メモ1件分の要素を作成
  const memoItemElement = createMemoItem(memoText);

  // ulに追加(要素追加)
  memoListElement.appendChild(memoItemElement);

  // 入力欄を空にする(テキスト変更)
  memoInputElement.value = '';

  // 件数表示を更新
  updateMemoCount();
});
JavaScript

ここでのポイントは、

  • 「何をしているか」が一目で分かるような流れになっていること
  • 入力チェック → 要素追加 → テキスト変更 → 件数更新 という順番が明確になっていること

です。

イベントの応用:Enterキーでメモを追加する

キーボード操作にも反応させる

フォーム系のUIでは、 Enterキーで操作できると使いやすくなります。

// ▼ 入力欄でEnterキーが押されたときにメモを追加します
memoInputElement.addEventListener('keydown', function (event) {
  if (event.key === 'Enter') {
    // 「追加」ボタンと同じ処理を呼び出します
    addButtonElement.click();
  }
});
JavaScript

ここでの重要ポイントは、

  • keydown イベントで event.key をチェックしていること
  • Enterキーが押されたときに、 わざわざ同じ処理をコピーせず、addButtonElement.click() を呼び出していること
    • これにより、「追加処理の本体は常に1か所」に保たれます。

要素削除の応用:「すべて削除」ボタン

子要素をまとめて削除する

「すべて削除」ボタンでは、 memoList 内のすべてのメモを削除します。

// ▼ 「すべて削除」ボタンのクリックイベント
clearAllButtonElement.addEventListener('click', function () {
  // 確認ダイアログを出して、誤操作を防ぎます
  const ok = confirm('すべてのメモを削除しますか?');
  if (!ok) {
    return;
  }

  // ▼ memoList内のすべての子要素を削除します
  // 方法1:innerHTMLを空にする(簡単)
  memoListElement.innerHTML = '';

  // ▼ 件数表示を更新します
  updateMemoCount();
});
JavaScript

ここでのポイントは、

  • confirm() を使って、ユーザーに確認してから削除していること
  • innerHTML = '' で、memoList 内のすべての子要素を一気に削除していること
    • 個別に remove() を呼ぶ方法もありますが、 「全部消す」場合はこの方法がシンプルです。

クラス操作の応用:「重要メモを強調」ボタン

重要メモだけに追加のクラスを付ける

「重要メモを強調」ボタンでは、 すでに .important クラスが付いているメモに対して、 さらに別のクラスを付ける、ということもできます。

ここでは、 「重要メモだけを少し大きく表示する」例を考えます。

まず、CSSにクラスを追加します。

<style>
  /* 既存のスタイルに追加 */
  .highlighted {
    transform: scale(1.03);
    box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
  }
</style>

次に、JavaScriptで「重要メモだけに .highlighted を付ける」処理を書きます。

// ▼ 「重要メモを強調」ボタンのクリックイベント
highlightImportantButtonElement.addEventListener('click', function () {
  // memoList内のすべてのメモ要素を取得します
  const memoItems = memoListElement.querySelectorAll('.memo-item');

  memoItems.forEach(function (item) {
    if (item.classList.contains('important')) {
      // 重要メモにはhighlightedクラスを付けます
      item.classList.add('highlighted');
    } else {
      // 重要でないメモからはhighlightedクラスを外します
      item.classList.remove('highlighted');
    }
  });
});
JavaScript

ここでの重要ポイントは、

  • querySelectorAll('.memo-item') で、すべてのメモ要素を取得していること
  • classList.contains('important') で「重要かどうか」を判定していること
  • 状態に応じて classList.add()classList.remove() を使い分けていること

です。

完成コード(総復習+拡張版メモアプリ)

ここまでの内容を1つにまとめた完成コードです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Day 44 後半:DOM総復習 メモアプリ拡張</title>
  <style>
    body {
      font-family: sans-serif;
      padding: 20px;
    }

    #memoInput {
      width: 240px;
      padding: 6px;
    }

    #addButton,
    #clearAllButton,
    #highlightImportantButton {
      padding: 6px 12px;
      margin-left: 4px;
      cursor: pointer;
    }

    #memoList {
      margin-top: 16px;
      padding-left: 0;
      list-style: none;
    }

    .memo-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 6px 8px;
      margin-bottom: 4px;
      border: 1px solid #ccc;
      border-radius: 4px;
      transition: transform 0.1s ease, box-shadow 0.1s ease;
    }

    .important {
      background-color: #fff3cd;
      border-color: #ffecb5;
      font-weight: bold;
    }

    .highlighted {
      transform: scale(1.03);
      box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
    }

    .delete-button {
      padding: 2px 8px;
      font-size: 0.8rem;
      cursor: pointer;
      color: #fff;
      background-color: #dc3545;
      border: none;
      border-radius: 4px;
    }

    #memoCount {
      margin-top: 12px;
      font-size: 0.9rem;
      color: #555;
    }
  </style>
</head>
<body>
  <h1>DOM総復習:メモリストアプリ拡張</h1>

  <input id="memoInput" type="text" placeholder="メモを入力してください">
  <button id="addButton">追加</button>
  <button id="clearAllButton">すべて削除</button>
  <button id="highlightImportantButton">重要メモを強調</button>

  <p id="memoCount">メモ件数:0件</p>

  <ul id="memoList"></ul>

  <script>
    // ▼ 要素取得
    const memoInputElement = document.getElementById('memoInput');
    const addButtonElement = document.getElementById('addButton');
    const clearAllButtonElement = document.getElementById('clearAllButton');
    const highlightImportantButtonElement = document.getElementById('highlightImportantButton');
    const memoListElement = document.getElementById('memoList');
    const memoCountElement = document.getElementById('memoCount');

    // ▼ メモ件数を更新する関数(テキスト変更)
    function updateMemoCount() {
      const memoItems = memoListElement.querySelectorAll('li');
      const count = memoItems.length;
      memoCountElement.textContent = `メモ件数:${count}件`;
    }

    // ▼ メモ1件分の要素を作成する関数(要素追加+イベント+クラス操作)
    function createMemoItem(memoText) {
      const memoItemElement = document.createElement('li');
      memoItemElement.classList.add('memo-item');

      const memoTextElement = document.createElement('span');
      memoTextElement.textContent = memoText;

      const deleteButtonElement = document.createElement('button');
      deleteButtonElement.textContent = '削除';
      deleteButtonElement.classList.add('delete-button');

      memoItemElement.appendChild(memoTextElement);
      memoItemElement.appendChild(deleteButtonElement);

      // メモ本文クリックで「重要」クラスを切り替え
      memoTextElement.addEventListener('click', function () {
        memoItemElement.classList.toggle('important');
      });

      // 削除ボタンクリックでこのメモを削除
      deleteButtonElement.addEventListener('click', function () {
        memoItemElement.remove();
        updateMemoCount();
      });

      return memoItemElement;
    }

    // ▼ 「追加」ボタンのクリックイベント
    addButtonElement.addEventListener('click', function () {
      const memoText = memoInputElement.value;

      if (memoText.trim() === '') {
        alert('メモを入力してください。');
        return;
      }

      const memoItemElement = createMemoItem(memoText);
      memoListElement.appendChild(memoItemElement);

      memoInputElement.value = '';
      updateMemoCount();
    });

    // ▼ 入力欄でEnterキーが押されたときにメモを追加
    memoInputElement.addEventListener('keydown', function (event) {
      if (event.key === 'Enter') {
        addButtonElement.click();
      }
    });

    // ▼ 「すべて削除」ボタンのクリックイベント(要素削除)
    clearAllButtonElement.addEventListener('click', function () {
      const ok = confirm('すべてのメモを削除しますか?');
      if (!ok) {
        return;
      }

      memoListElement.innerHTML = '';
      updateMemoCount();
    });

    // ▼ 「重要メモを強調」ボタンのクリックイベント(クラス操作)
    highlightImportantButtonElement.addEventListener('click', function () {
      const memoItems = memoListElement.querySelectorAll('.memo-item');

      memoItems.forEach(function (item) {
        if (item.classList.contains('important')) {
          item.classList.add('highlighted');
        } else {
          item.classList.remove('highlighted');
        }
      });
    });

    // ▼ 初期状態の件数表示
    updateMemoCount();
  </script>
</body>
</html>

練習用テンプレート:自分で機能を足してみるためのベース

最後に、少し簡略化した練習用テンプレートを紹介します。 ここから「検索機能」「ソート機能」などを自分で足してみるのも良い練習になります。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Day 44 後半:DOM総復習 練習テンプレート</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    #memoList { margin-top: 16px; padding-left: 0; list-style: none; }
    .memo-item { display: flex; justify-content: space-between; padding: 6px 8px; border: 1px solid #ccc; margin-bottom: 4px; }
    .important { background-color: #fff3cd; font-weight: bold; }
    .highlighted { transform: scale(1.03); box-shadow: 0 0 4px rgba(0,0,0,0.2); }
    .delete-button { padding: 2px 8px; font-size: 0.8rem; cursor: pointer; }
    #memoCount { margin-top: 12px; font-size: 0.9rem; color: #555; }
  </style>
</head>
<body>
  <h1>DOM総復習 練習テンプレート</h1>

  <input id="memoInput" type="text" placeholder="メモ">
  <button id="addButton">追加</button>
  <button id="clearAllButton">すべて削除</button>
  <button id="highlightImportantButton">重要メモを強調</button>

  <p id="memoCount">メモ件数:0件</p>

  <ul id="memoList"></ul>

  <script>
    console.log('--- DOM総復習 練習開始 ---');

    const memoInputElement = document.getElementById('memoInput');
    const addButtonElement = document.getElementById('addButton');
    const clearAllButtonElement = document.getElementById('clearAllButton');
    const highlightImportantButtonElement = document.getElementById('highlightImportantButton');
    const memoListElement = document.getElementById('memoList');
    const memoCountElement = document.getElementById('memoCount');

    function updateMemoCount() {
      const count = memoListElement.querySelectorAll('li').length;
      memoCountElement.textContent = `メモ件数:${count}件`;
    }

    function createMemoItem(memoText) {
      const li = document.createElement('li');
      li.classList.add('memo-item');

      const span = document.createElement('span');
      span.textContent = memoText;

      const button = document.createElement('button');
      button.textContent = '削除';
      button.classList.add('delete-button');

      li.appendChild(span);
      li.appendChild(button);

      span.addEventListener('click', () => {
        li.classList.toggle('important');
      });

      button.addEventListener('click', () => {
        li.remove();
        updateMemoCount();
      });

      return li;
    }

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

      if (text.trim() === '') {
        alert('メモを入力してください。');
        return;
      }

      const li = createMemoItem(text);
      memoListElement.appendChild(li);
      memoInputElement.value = '';
      updateMemoCount();
    });

    memoInputElement.addEventListener('keydown', (event) => {
      if (event.key === 'Enter') {
        addButtonElement.click();
      }
    });

    clearAllButtonElement.addEventListener('click', () => {
      const ok = confirm('すべて削除しますか?');
      if (!ok) return;
      memoListElement.innerHTML = '';
      updateMemoCount();
    });

    highlightImportantButtonElement.addEventListener('click', () => {
      const items = memoListElement.querySelectorAll('.memo-item');
      items.forEach((item) => {
        if (item.classList.contains('important')) {
          item.classList.add('highlighted');
        } else {
          item.classList.remove('highlighted');
        }
      });
    });

    updateMemoCount();
    console.log('--- DOM総復習 練習テンプレートの準備が完了しました ---');
  </script>
</body>
</html>

Day 44 後半のまとめ

Day 44後半では、

  • 前半で作ったメモアプリに、 件数表示・すべて削除・重要メモ強調・Enterキー対応を追加し、 DOM操作の基本6セットを「少し複雑な振る舞い」にまで拡張したこと。
  • 要素取得・テキスト変更・クラス操作・イベント・要素追加・要素削除を、 それぞれ単体ではなく 組み合わせて使う感覚 を育てたこと。
  • 関数に処理をまとめることで、 「何をしているか」が読みやすく、変更しやすいコード構造を体験したこと。

を整理しました。

ここまでできると、 小さなWebアプリなら自分で設計して組み立てていける土台ができています。 この総復習をベースに、次のステップでは「データ構造」や「状態管理」にも踏み込んでいけます。

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