【実践】JavaScriptでTODOアプリを作成しよう! 第7回 ボタンに「役割」を与える

JavaScript学習ガイド

こんにちは、Reiです!

前回は、入力した文字を「未完了リスト」に追加するところまで実装しました。

今回はその続きとして、TODOを操作できるようにしていきます。


TODOに操作機能を追加する

前回のステップで、
「入力したTODOを未完了リストに表示する」という機能が完成しました。

ここまでで、TODOを追加することはできる状態 になっています。


ただ、今のままだと

・TODOを消すことができない
・完了したタスクを管理できない

といった状態で、まだ表示されているだけの状態です。

そこで今回は、

・TODOを削除する
・TODOを完了状態にする

といった処理を追加していきます。


このステップを進めることで、
ユーザーの操作に反応する「アプリらしい動き」 ができるようになります。

順番に実装していきましょう!


1. ボタンにクリックイベントを紐付ける

まずは、作成した「完了ボタン」「削除ボタン」が押されたことを
JavaScriptで検知できるようにします。

【編集ファイル:src/index.js】

〜省略〜

  // 完了ボタンの生成
  const completeButton = document.createElement("button");
  completeButton.innerText = "完了";
  completeButton.addEventListener("click", () => {
    alert("完了ボタンが押されました");
  });

  // 削除ボタンの生成
  const deleteButton = document.createElement("button");
  deleteButton.innerText = "削除";
  deleteButton.addEventListener("click", () => {
    alert("削除ボタンが押されました");
  });

〜省略〜

まずは alert を使って、ボタンが正しく反応しているか確認しておきましょう!


2. 削除ボタンの実装(要素を特定して削除する)

次に、「削除ボタンが押されたら、そのTODOだけを消す」処理を実装します。
ポイントは、押されたボタンが属している行(li)を特定すること です。

【編集ファイル:src/index.js】

deleteButton.addEventListener("click", () => {
  alert("削除ボタンが押されました"); // 削除

  // 1. 押された削除ボタンから見て、一番近い「liタグ」を探し出す
  const deleteTarget = deleteButton.closest("li");

  // 2. 未完了リスト(ul)から、特定した liタグを削除する
  document.getElementById("incomplete-list").removeChild(deleteTarget);
});
  • closest(“li”)
    指定した要素から親方向にたどっていき、最も近い li 要素を取得する命令です。
    これにより、「どのボタンが押されたか」に応じて、そのボタンが属している行だけを正しく特定できるようになります。

  • removeChild()
    親要素(ul)から、指定した子要素(li)を削除する命令です。
    この処理によって、対象のTODOが画面上から完全に消えるようになります。

この2つを組み合わせることで、
「どの削除ボタンが押されても、その行だけ削除する」という動きが実現することができます。


3. 完了ボタンの実装(要素を移動する)

次は、TODOを「未完了 → 完了リスト」に移動させる処理です。

【編集ファイル:src/index.js】

completeButton.addEventListener("click", () => {
  alert("完了ボタンが押されました"); // 削除

  // 移動対象の li を特定
  const moveTarget = completeButton.closest("li");

   // ボタン要素を削除
   const row = moveTarget.querySelector(".list-row");
   row.querySelectorAll("button").forEach((btn) => btn.remove());

  // 完了エリアの ul に移動させる
  document.getElementById("complete-list").appendChild(moveTarget);
});

ここで重要なのは、
すでに存在している要素を渡すと「コピー」ではなく「移動」になる という点です。

そのため、未完了リストから消えつつ、完了リストに現れるという動きが自然に実現できます。


今回の処理の流れ

ここまでの処理を整理すると、
ボタンがクリックされたときに次の順番で処理が行われます。

  1. ユーザーがボタンをクリックする
  2. クリックイベントが発火する
  3. closestで対象のliを取得する
  4. removeChild または appendChild で画面を更新する

このように、

「どの要素に対して、何をするか」

を組み立てていくのが、JavaScriptで画面を操作する基本的な考え方です。


全体像の確認

最終的に、以下のような 構成 になっていればOKです。

  • index.html
    完了リストのulに id=”complete-list” が付いている
  • src/index.js
    各ボタンにクリックイベントが登録され、削除・移動の処理が実装されている

このように ボタン1つ1つに役割を定義する 手順を踏むことで、
静的な「見た目」だったTODOリストが、ユーザーの操作に反応する「アプリ」へと進化します。


【完成ファイル:src/index.js】

〜省略〜

  // 完了ボタンの生成
  const completeButton = document.createElement("button");
  completeButton.innerText = "完了";
  completeButton.addEventListener("click", () => {
    // 完了リストに移動
    const moveTarget = completeButton.closest("li");

    // ボタン要素を削除
    const row = moveTarget.querySelector(".list-row");
    row.querySelectorAll("button").forEach((btn) => btn.remove());

    document.getElementById("complete-list").appendChild(moveTarget);
  });

  // 削除ボタンの生成
  const deleteButton = document.createElement("button");
  deleteButton.innerText = "削除";
  deleteButton.addEventListener("click", () => {
    // 未完了リストから削除
    const deleteTarget = deleteButton.closest("li");
    document.getElementById("incomplete-list").removeChild(deleteTarget);
  });

〜省略〜

まとめ

今回は、JavaScriptを使って
「TODOを操作できる機能」 を実装しました。

\\ 今回のまとめ //

・ addEventListener でクリックイベントを登録する
・ closest を使って操作対象の要素を特定する
・ removeChild で削除、appendChild で移動する
・ 同じ処理は関数化して再利用する


ここまで実装できたら、TODOアプリとしての基本機能はひと通り完成です 🎉・:*:・。

JavaScriptを使って「画面上の要素を狙い通りに動かす」という、
プログラミングの醍醐味をしっかり体験できたのではないでしょうか?


もし、「思うように動かない…」という部分があっても大丈夫です!
コードが少し複雑になってきたので、どこか一文字打ち間違えているだけかもしれません。


そこで次回は、今回作成したプログラムの全量版(完成コード)を掲載します。

自分の書いたコードとじっくり見比べて、答え合わせをしてみてください。
「どこで何をしているのか」を改めて一つひとつ確認することで、
理解がさらにグッと深まるはずです!

コメント

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