ToDoリストを作る——小さなWebアプリでコースの締めくくり
レッスン8:ToDoリストを作る——小さなWebアプリでコースの締めくくり
このレッスンで学ぶこと
- これまでの知識を組み合わせてToDoリストを実装できる
- 配列を状態として保持し、画面に反映するパターンを身につける
- JavaScriptがブラウザだけでなくサーバー・デスクトップ・モバイルでも動くことを知る
- コース修了後の学習方向を選べる
レッスン1から7まで、JavaScriptの基本文法・配列とオブジェクト・DOM操作・イベント処理を学んできました。最後のレッスンでは、これらをすべて使って小さなWebアプリ「ToDoリスト」を実装します。コースの締めくくりとして、JavaScriptがブラウザ以外でも広く使われていることを紹介し、次の学習ステップを案内します。
何を作るのか
これから作るのは、項目を入力欄に書き込んで「追加」を押すと、リストに項目が増え、各項目の「削除」ボタンで消せるシンプルなToDoリストです。実際のWebアプリの基本動作を、ひと通り体験できるアプリです。
主な機能:
- 入力欄に項目を書く
- 「追加」ボタンを押すと、リストに項目が追加される
- 各項目には「削除」ボタンが付き、押すと項目が消える
- 入力欄が空のときは追加できないようにする
ステップ1:HTMLを準備する
my-website フォルダの index.html の .js-demo セクションの後ろあたり(または別のセクションとして)に、次のHTMLを追加してください。
<section class="todo-app">
<h2>ToDoリスト</h2>
<form id="todoForm">
<input type="text" id="todoInput" placeholder="やることを入力" required>
<button type="submit">追加</button>
</form>
<ul id="todoList"></ul>
</section>
<form> の中に入力欄と追加ボタンを置き、その下の <ul> がToDoの項目を並べる場所です。<ul> は最初は空です。JavaScriptが項目を追加していきます。
assets/css/style.css の最後に、見栄え用のスタイルも追加します。
.todo-app {
background-color: #fff;
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
max-width: 500px;
margin-bottom: 40px;
}
.todo-app form {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
.todo-app input[type="text"] {
flex: 1;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
.todo-app button {
padding: 8px 16px;
background-color: #2c3e50;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
.todo-app ul {
list-style: none;
padding: 0;
margin: 0;
}
.todo-app li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid #eee;
}
.todo-app li button {
background-color: #c0392b;
padding: 4px 10px;
font-size: 14px;
}
ここまでで保存してブラウザを再読み込みすると、ToDoリスト用の見た目が表示されます。動作はまだありません。
ステップ2:状態を保持する配列を用意する
assets/js/main.js の最後に、ToDoリスト用のコードをまとめて書いていきます。
まず、ToDo項目を保持する配列と、必要な要素の取得から始めます。
// ToDoリストの状態
const todos = [];
// 要素の取得
const todoForm = document.querySelector("#todoForm");
const todoInput = document.querySelector("#todoInput");
const todoList = document.querySelector("#todoList");
todos 配列が、現在のToDo項目を保持する「状態」です。最初は空です。これから追加・削除のたびにこの配列を更新し、画面(<ul>)に反映していきます。
💡 ポイント 「状態(データ)」と「画面表示」を分けて考えるのが、Webアプリの基本姿勢です。データは配列やオブジェクトで管理し、画面はそのデータを反映するだけ。React・Vueといったフレームワークも、この発想を強力に推し進めたものです。
ステップ3:画面を再描画する関数を作る
データを画面に反映する処理を、関数として独立させます。データが変わったら、この関数を呼ぶだけで画面が最新の状態になる、という設計です。
function renderTodos() {
todoList.innerHTML = "";
todos.forEach((todo, index) => {
const li = document.createElement("li");
li.textContent = todo;
const deleteButton = document.createElement("button");
deleteButton.textContent = "削除";
deleteButton.addEventListener("click", () => {
todos.splice(index, 1);
renderTodos();
});
li.appendChild(deleteButton);
todoList.appendChild(li);
});
}
新しく出てきた要素を整理します。
document.createElement("li"):HTMLの<li>要素を新しく作る要素.appendChild(子要素):要素を別の要素の子として追加する配列.splice(インデックス, 削除数):配列の指定位置から要素を取り除く
renderTodos が呼ばれると、<ul> の中身を一度空にしてから、todos 配列の各要素について <li> と削除ボタンを作って追加します。削除ボタンには「自分のインデックスを使って todos から1つ削除し、再描画する」処理が登録されます。
🔰 初学者の方へ
innerHTML = ""で一度全部消してから、配列の現状を反映するために作り直す——これが「再描画」と呼ばれるパターンです。一見もったいないように見えますが、コードがシンプルになりミスが減るため、入門段階では推奨されるやり方です。
ステップ4:フォーム送信を受けて項目を追加する
レッスン7で学んだフォーム送信のパターンを使います。
todoForm.addEventListener("submit", (event) => {
event.preventDefault();
const text = todoInput.value.trim();
if (text === "") return;
todos.push(text);
todoInput.value = "";
renderTodos();
});
ポイントは次の3つです。
event.preventDefault()で送信時の再読み込みを止めるtext.trim()で前後の空白を取り除く(空白だけのToDoを防ぐため)- 空でなければ
todosに追加し、入力欄をリセットして再描画
📝 補足
returnを関数の途中で書くと、そこで関数を抜けます。空文字のときに何もせず関数を終える、という早期リターンの書き方は、コードを読みやすくする定番のテクニックです。
ステップ5:完成形を確認する
ここまでに書いたToDoリストのコードをまとめると、次のようになります。
// ToDoリスト
// 状態
const todos = [];
// 要素の取得
const todoForm = document.querySelector("#todoForm");
const todoInput = document.querySelector("#todoInput");
const todoList = document.querySelector("#todoList");
// 画面の再描画
function renderTodos() {
todoList.innerHTML = "";
todos.forEach((todo, index) => {
const li = document.createElement("li");
li.textContent = todo;
const deleteButton = document.createElement("button");
deleteButton.textContent = "削除";
deleteButton.addEventListener("click", () => {
todos.splice(index, 1);
renderTodos();
});
li.appendChild(deleteButton);
todoList.appendChild(li);
});
}
// フォーム送信で項目を追加
todoForm.addEventListener("submit", (event) => {
event.preventDefault();
const text = todoInput.value.trim();
if (text === "") return;
todos.push(text);
todoInput.value = "";
renderTodos();
});
保存してブラウザを再読み込みし、入力欄に「牛乳を買う」と入れて「追加」を押すと、リストに「牛乳を買う 削除」と表示されます。続けて「掃除をする」「メールを返す」など追加してみてください。各項目の「削除」を押すと、その項目だけが消えます。
これがあなたが作った最初のWebアプリです。
💡 ポイント ToDoリストは「Webアプリの hello world」と呼ばれることもあるほど、初学者がWebアプリの仕組みを学ぶための定番題材です。配列で状態を管理し、画面を再描画し、イベントで状態を変える——これがあらゆるWebアプリの基本構造です。今回学んだパターンは、商品リスト・コメント一覧・SNSのタイムラインなど、さまざまなアプリの土台になります。
改善のヒント
物足りなく感じる方のために、自分で挑戦できる改善案をいくつか紹介します。
- 完了チェック機能:チェックボックスを追加し、完了したToDoに打消し線を付ける
- 件数表示:「現在の件数:3件」のように、リストの上に件数を表示する
- 編集機能:項目をクリックすると編集できるようにする
- 保存機能:ブラウザを閉じても項目が残るように、
localStorageを使う
最後の localStorage は、ブラウザに少量のデータを保存できる仕組みです。簡単な例だけ紹介します。
// データを保存
localStorage.setItem("todos", JSON.stringify(todos));
// データを読み込み
const saved = JSON.parse(localStorage.getItem("todos") || "[]");
JSON.stringify で配列を文字列化して保存し、JSON.parse で読み込みます。本コースでは深く扱いませんが、興味があればぜひ調べて実装してみてください。
📖 もっと詳しく 本格的なToDoアプリを作るには、項目に固有のIDを持たせて削除のときにインデックスではなくIDで識別する設計が望ましいです。今のままだと、削除時にイベントハンドラがその時点のインデックスを記憶してしまうため、複雑な操作ですれ違いが起きる可能性があります。実用には次のステップで紹介するフレームワークを使うのが現実的です。
JavaScriptの広がり——ブラウザだけじゃない
ここからは「次のステップ案内」のセクションです。本コースは「ブラウザで動くJavaScript」に絞って学んできましたが、JavaScriptはブラウザの外でも非常に広い用途で使われています。コース修了後の学習の参考に、3つの広がりを簡単に紹介します。
1. サーバーサイドのJavaScript——Node.js
Node.jsは、JavaScriptをブラウザの外、つまりパソコンやサーバーの上で動かすための実行環境です。2009年に登場し、現在ではバックエンド開発の主要言語のひとつになっています。
Node.jsを使うと、こんなことができます。
- Webサーバーを立ち上げて、リクエストに応じてレスポンスを返す
- ファイルを読み書きしたり、ファイル操作の自動化スクリプトを書いたりする
- 自分で開発したコマンドラインツールを作る
- データベースとつなぐサーバー側のロジックを書く
「フロントエンド(ブラウザ)もJavaScript、バックエンド(サーバー)もJavaScript」という構成が、Node.jsで実現できます。同じ言語で全部書ける利点から、多くのWebサービスで採用されています。
2. デスクトップ・モバイルアプリ——Electron・React Native
JavaScriptでデスクトップアプリやスマートフォンアプリを作ることもできます。
Electron は、Webの技術(HTML・CSS・JavaScript)を使ってデスクトップアプリを作るためのフレームワークです。Visual Studio Code、Slack、Discordなど、有名なデスクトップアプリの多くがElectronで作られています。
React Native は、JavaScriptとReactの考え方を使って、iOSとAndroidのスマートフォンアプリを作るためのフレームワークです。1つのコードベースで両方のOSに対応できる強みがあります。
3. フロントエンドのフレームワーク——React・Vue・Astro
ブラウザJavaScriptの世界でも、大規模なアプリを効率よく作るためのフレームワーク・ライブラリが多数あります。代表的なものを3つ挙げます。
React は、Meta(旧Facebook)が開発したUIライブラリです。コンポーネント単位でUIを組み立てる発想で、大規模なアプリで広く使われています。
Vue は、シンプルさと学習しやすさを重視したフレームワークです。HTMLに近い書き方ができるため、入門者にも扱いやすいと評判です。
Astro は、コンテンツ重視のWebサイトに向いた、近年注目されているフレームワークです。必要最小限のJavaScriptだけを送り出す設計で、表示が速いサイトを作れます。
これらは本コースの内容を土台にして学べます。「素のJavaScript(バニラJS)」をしっかり理解してからフレームワークに進むほうが、結果として早く身につくと言われています。
💡 ポイント JavaScriptはWebに留まらず、サーバー・デスクトップ・モバイル・組み込み機器まで広く使われている言語です。本コースの基礎を持っていれば、これらの世界に進む土台ができています。慌ててすべてに手を出さず、興味のある分野からひとつずつ深めていけば大丈夫です。
このコースの先へ——次のステップ
本コースでJavaScriptの基礎を身につけました。お疲れさまでした。手元には、これまでに作ったページに、動きと対話を加えた小さなWebアプリが残っているはずです。
次のステップとしては、次のような方向が考えられます。
1. 学んだ知識で何かを作る:もう1つ別のテーマでToDoリストを作る、簡単なクイズアプリを作る、自作のサイトに JavaScript で動きを追加する、など。「学んだ→作る」の繰り返しが、もっとも力になる学習法です。
2. JavaScriptをさらに深める:本コースでは扱わなかったテーマがたくさんあります。非同期処理(async/await)、APIとの通信(fetch)、モジュール化(import/export)などです。
3. フレームワークに進む:React・Vue・Astroのような道具を学ぶと、より大規模なWebアプリが作れるようになります。
4. Node.jsを学んでサーバー側に挑戦する:JavaScriptでサーバー側のプログラムを書けるようになると、Webサービスを丸ごと自分で作る道が開けます。
5. Webサイトを公開する:作ったサイトを実際にインターネットに出してみる。GitHub PagesやNetlify、Vercelといったサービスは無料で始められます。
🔰 初学者の方へ 全部やる必要はありません。1つずつ、自分のペースで進んでください。プログラミングは「わかった」と「使える」の間に大きな差があります。本コースで学んだ知識を、自分のプロジェクトで何度も使ってみることが、結局のところ最も力になります。
まとめ
このレッスンでは、以下のことを学びました。
- 配列で状態を保持し、画面を再描画するパターンでToDoリストを実装した
createElement・appendChildで動的に要素を作って追加できるspliceで配列の特定要素を削除できる- JavaScriptはサーバー(Node.js)、デスクトップ(Electron)、モバイル(React Native)、フロントエンドフレームワーク(React・Vue・Astro)など、ブラウザ以外でも広く使われている
- コース修了後は、自分で何かを作る・JavaScriptを深める・フレームワークに進む・サーバー側に挑戦する・サイトを公開する、などの方向がある
ここまでJavaScriptの基礎を一緒に学びました。HTMLとCSSで作った静的なページに、動きと対話を加える力が手に入ったはずです。何度もコードを書いて、自分なりのWebアプリを作ってみてください。
最後の総復習テストでコース全体を確認したら、ぜひ次の挑戦に進んでください。応援しています。
確認クイズ
このレッスンの理解度をチェックしましょう。