【1時間で完成】JavaScriptでTODOアプリを作る!初心者でも挫折しない実装ガイド
こんにちは、とまだです。
「JavaScriptでTODOアプリを作りたいけど、何から始めればいいかわからない...」
そんな悩みを抱えていませんか?
私も最初にTODOアプリを作ろうとした時、いきなり複雑なコードを見て圧倒されてしまいました。結局、3回も挫折して、4回目でようやく完成させることができたんです。
今回は、その経験を活かしてたった1時間で動くTODOアプリを一緒に作っていきましょう。難しい機能は後回しにして、まずは「動くものを作る」ことに集中します。
TODOアプリ作成で身につく5つのスキル
TODOアプリは「プログラミング学習の定番」と呼ばれています。
なぜかというと、Webアプリ開発に必要な基礎スキルが凝縮されているからなんです。
1. DOM操作の基本
画面に要素を追加したり、削除したりする操作です。
たとえば、料理のレシピに材料を追加するような感覚で、画面に新しいタスクを表示できるようになります。
2. イベント処理の理解
ボタンをクリックしたら何かが起こる、という仕組みです。
自動販売機でボタンを押したらジュースが出てくるように、クリックに反応するプログラムが書けるようになります。
3. 配列やオブジェクトの扱い方
複数のデータをまとめて管理する方法を学べます。
本棚に本を整理するように、タスクを整理整頓して管理できるようになるんです。
4. 状態管理の基礎
アプリの「今の状態」を管理する考え方が身につきます。
冷蔵庫の中身を把握しているように、今どんなタスクがあるかを常に把握できるようになります。
5. データの永続化(保存)
ブラウザを閉じてもデータが消えない仕組みを作れます。
日記を書いて保存するように、大切なタスクを失わずに済むようになるんです。
今回作るTODOアプリの完成イメージ
まずは、完成形を見てみましょう。
シンプルですが、以下の機能を持つTODOアプリを作ります:
- タスクの追加(Enterキーでも追加可能)
- タスクの完了/未完了の切り替え
- タスクの削除
- データの自動保存(ブラウザを閉じても残る)
見た目はシンプルですが、実用的な機能は全て揃っています。
必要な準備はたった2つだけ
1. テキストエディタ
VSCodeがおすすめですが、メモ帳でも大丈夫です。
コードを書ける環境があればOKです。
2. Webブラウザ
Chrome、Firefox、Safariなど、お好きなブラウザを使ってください。
最新版であれば問題ありません。
これだけです!
特別なツールのインストールは不要なので、すぐに始められます。
ステップ1:HTMLで骨組みを作る(5分)
まずは、TODOアプリの見た目の部分を作ります。
HTMLファイルを作成して、以下のコードを書いてみましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>シンプルTODOアプリ</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>TODOリスト</h1>
<!-- タスク入力エリア -->
<div class="input-area">
<input type="text" id="taskInput" placeholder="タスクを入力してください">
<button id="addButton">追加</button>
</div>
<!-- タスク一覧エリア -->
<ul id="taskList"></ul>
</div>
<script src="script.js"></script>
</body>
</html>
このHTMLは、家の設計図のようなものです。
入力欄、追加ボタン、タスクを表示する場所を用意しました。
ステップ2:CSSで見た目を整える(10分)
次に、見た目を少し整えましょう。
style.cssというファイルを作成して、以下のコードを書きます。
/* 全体のスタイル */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 20px;
}
.container {
max-width: 500px;
margin: 0 auto;
background-color: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
}
/* 入力エリアのスタイル */
.input-area {
display: flex;
margin-bottom: 20px;
}
#taskInput {
flex: 1;
padding: 10px;
border: 2px solid #e0e0e0;
border-radius: 5px;
font-size: 16px;
outline: none;
}
#taskInput:focus {
border-color: #4CAF50;
}
#addButton {
margin-left: 10px;
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s;
}
#addButton:hover {
background-color: #45a049;
}
/* タスクリストのスタイル */
#taskList {
list-style: none;
padding: 0;
}
.task-item {
display: flex;
align-items: center;
padding: 15px;
margin-bottom: 10px;
background-color: #f9f9f9;
border-radius: 5px;
transition: all 0.3s;
}
.task-item:hover {
background-color: #f0f0f0;
}
.task-item.completed {
opacity: 0.6;
}
.task-item.completed .task-text {
text-decoration: line-through;
}
.task-checkbox {
margin-right: 15px;
width: 20px;
height: 20px;
cursor: pointer;
}
.task-text {
flex: 1;
font-size: 16px;
color: #333;
}
.delete-button {
background-color: #ff4444;
color: white;
border: none;
padding: 5px 15px;
border-radius: 3px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.3s;
}
.delete-button:hover {
background-color: #cc0000;
}
これで、見た目がグッと良くなりました。
まるで部屋の模様替えをしたような感じですね。
ステップ3:JavaScriptで動きをつける(40分)
さあ、いよいよメインディッシュです!
script.jsというファイルを作成して、TODOアプリに命を吹き込みましょう。
基本的な要素の取得
// 必要な要素を取得
const taskInput = document.getElementById('taskInput');
const addButton = document.getElementById('addButton');
const taskList = document.getElementById('taskList');
// タスクを保存する配列
let tasks = [];
まずは、HTMLで作った要素をJavaScriptで操作できるようにします。
これは、リモコンで家電を操作する準備をするようなものです。
タスクを追加する機能
// タスクを追加する関数
const addTask = () => {
const taskText = taskInput.value.trim();
// 空の入力は無視
if (!taskText) {
alert('タスクを入力してください!');
return;
}
// 新しいタスクオブジェクトを作成
const newTask = {
id: Date.now(), // 一意のIDとして現在時刻を使用
text: taskText,
completed: false
};
// 配列に追加
tasks.push(newTask);
// 入力欄をクリア
taskInput.value = '';
// 画面を更新
renderTasks();
// ローカルストレージに保存
saveTasks();
};
この関数は、新しいタスクを作って配列に追加します。
レシピに新しい材料を追加するような感じですね。
タスクを画面に表示する機能
// タスク一覧を表示する関数
const renderTasks = () => {
// 一旦リストを空にする
taskList.innerHTML = '';
// 各タスクを表示
tasks.forEach(task => {
// リスト項目を作成
const li = document.createElement('li');
li.className = 'task-item';
if (task.completed) {
li.classList.add('completed');
}
// チェックボックスを作成
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.className = 'task-checkbox';
checkbox.checked = task.completed;
checkbox.onchange = () => toggleTask(task.id);
// タスクテキストを作成
const span = document.createElement('span');
span.className = 'task-text';
span.textContent = task.text;
// 削除ボタンを作成
const deleteBtn = document.createElement('button');
deleteBtn.className = 'delete-button';
deleteBtn.textContent = '削除';
deleteBtn.onclick = () => deleteTask(task.id);
// 要素を組み立てる
li.appendChild(checkbox);
li.appendChild(span);
li.appendChild(deleteBtn);
// リストに追加
taskList.appendChild(li);
});
};
画面に表示する処理です。
本棚に本を並べていくように、タスクを一つずつ画面に配置していきます。
タスクの完了/未完了を切り替える機能
// タスクの完了状態を切り替える関数
const toggleTask = (id) => {
tasks = tasks.map(task => {
if (task.id === id) {
return { ...task, completed: !task.completed };
}
return task;
});
renderTasks();
saveTasks();
};
チェックボックスをクリックすると、タスクの状態が切り替わります。
電気のスイッチのように、ON/OFFを切り替える感じです。
タスクを削除する機能
// タスクを削除する関数
const deleteTask = (id) => {
if (confirm('本当に削除しますか?')) {
tasks = tasks.filter(task => task.id !== id);
renderTasks();
saveTasks();
}
};
不要になったタスクを削除します。
ゴミ箱に捨てる前に、本当に捨てていいか確認もしてくれます。
データを保存・読み込みする機能
// ローカルストレージに保存
const saveTasks = () => {
localStorage.setItem('tasks', JSON.stringify(tasks));
};
// ローカルストレージから読み込み
const loadTasks = () => {
const savedTasks = localStorage.getItem('tasks');
if (savedTasks) {
tasks = JSON.parse(savedTasks);
renderTasks();
}
};
ブラウザを閉じても、タスクが消えないようにする魔法です。
日記帳に書いて保存するような感じですね。
イベントリスナーの設定
// イベントリスナーを設定
addButton.addEventListener('click', addTask);
// Enterキーでも追加できるように
taskInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
addTask();
}
});
// ページ読み込み時にタスクを読み込む
window.addEventListener('load', loadTasks);
最後に、ボタンクリックやEnterキーに反応するように設定します。
これで、TODOアプリの完成です!
ステップ4:動作確認とカスタマイズ(5分)
動作確認のポイント
- タスクの追加: 入力欄に文字を入れて「追加」ボタンをクリック
- 完了チェック: チェックボックスをクリックして線が引かれるか確認
- 削除機能: 削除ボタンで本当に削除されるか確認
- データ保存: ブラウザを更新してもタスクが残っているか確認
さらに改良したい方へ
基本的なTODOアプリができたら、以下のような機能を追加してみるのも面白いです:
- タスクの編集機能
- 期限の設定
- カテゴリー分け
- フィルター機能(完了・未完了の表示切り替え)
- ドラッグ&ドロップでの並び替え
よくあるエラーと解決方法
1. 「○○ is not defined」というエラー
変数名のスペルミスが原因です。
大文字・小文字も含めて、正確に入力されているか確認してください。
2. クリックしても反応しない
イベントリスナーの設定を忘れている可能性があります。
addEventListenerの部分を再確認してみてください。
3. データが保存されない
ローカルストレージは、file://で開いたHTMLファイルでは動作しない場合があります。
簡易的なWebサーバーを立てるか、オンラインエディタを使ってみてください。
まとめ:次のステップへ
おめでとうございます!
これで、あなたも立派なTODOアプリを作ることができました。
最初は難しく感じたかもしれませんが、一つずつ理解していけば、意外とシンプルだったのではないでしょうか。
このTODOアプリで学んだスキルは、他のWebアプリ開発でも必ず役立ちます。
もし、もっと本格的にJavaScriptを学びたいと思ったら、私が運営しているLearning Next Schoolもチェックしてみてください。
月額約2,000円で、JavaScriptだけでなくTypeScriptやReactなども学び放題です。今回作ったようなTODOアプリをさらに発展させる方法も詳しく解説しています。
次は、あなたのオリジナルアプリを作ってみませんか?
きっと、今回の経験が大きな自信になっているはずです。
著者について

とまだ
フルスタックエンジニア
Learning Next の創設者。Ruby on Rails と React を中心に、プログラミング教育に情熱を注いでいます。初心者が楽しく学べる環境作りを目指しています。
著者の詳細を見る →