Day25 前半のゴール
いよいよ「ちゃんとした Web アプリ」に一歩踏み込むところです。
Day25 のテーマは TODOアプリ①:タスク追加の実装。
前半ではまず、
タスクを入力する画面を作る
「追加」ボタンでタスクを画面に増やす
最低限「使える」TODOアプリの形にする
ここまでを、初心者でも追えるように丁寧に組み立てていきます。
まずは「どんな TODO を作るか」を決める
機能を欲張らず、最小から始める
TODOアプリと聞くと、いろいろやりたくなります。
完了チェック、削除、編集、期限、タグ……。
でも、最初から全部やろうとすると、ほぼ確実に迷子になります。
前半でやるのは、あくまでこれだけです。
タスクを1行テキストで入力する
「追加」ボタンを押すと、下にタスクが増える
ページをリロードすると消えてもよい(保存はまだ)
つまり、「紙のメモ帳に箇条書きする」のと同じレベルの TODO です。
ここをしっかり作れると、その上に機能を積み上げやすくなります。
入力と出力の HTML を作る
入力欄・ボタン・一覧エリアを用意する
まずは画面の骨組みからいきます。
TODOアプリに必要なのは、この3つです。
タスクを入力するテキストボックス
タスクを追加するボタン
タスク一覧を表示する場所
それを HTML にすると、こうなります。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TODOアプリ</title>
</head>
<body>
<h1>TODOアプリ</h1>
<h2>タスク追加</h2>
<input id="taskInput" type="text" placeholder="やることを入力">
<button id="addButton">追加</button>
<h2>タスク一覧</h2>
<div id="taskList"></div>
<script src="app.js"></script>
</body>
</html>
ここで重要なのは、JavaScript から触る要素に id を付けていることです。
taskInput
addButton
taskList
この3つが、タスク追加の主役になります。
JavaScript から要素をつかまえる
DOM 要素を変数にしておく
app.js を作って、まずは DOM 要素を取得します。
const taskInputElement = document.getElementById("taskInput");
const addButtonElement = document.getElementById("addButton");
const taskListElement = document.getElementById("taskList");
JavaScriptこれで、
taskInputElement から入力値を読む
addButtonElement にクリックイベントを付ける
taskListElement にタスクを追加する
という準備が整いました。
「タスクを1つ画面に追加する」処理を書く
まずは 1 個だけ追加できればいい
いきなり「たくさんのタスク」ではなく、
「ボタンを押したら1つタスクが増える」というところから始めます。
addButtonElement.addEventListener("click", () => {
const text = taskInputElement.value;
const taskElement = document.createElement("p");
taskElement.textContent = text;
taskListElement.appendChild(taskElement);
});
JavaScriptこれで、
タスクを入力する
「追加」ボタンを押す
下の「タスク一覧」に p 要素が1つ増える
という動きになります。
ただし、このままだと問題があります。
空のままでも追加できてしまう
追加したあとも入力欄に前の文字が残る
ここを少しずつ改善していきます。
空のタスクを追加しないようにする
trim と if でシンプルにバリデーション
タスクが空のまま追加されると、
「何も書いてない行」が増えてしまい、見づらくなります。
なので、空文字は弾きます。
addButtonElement.addEventListener("click", () => {
const text = taskInputElement.value.trim();
if (text === "") {
return;
}
const taskElement = document.createElement("p");
taskElement.textContent = text;
taskListElement.appendChild(taskElement);
});
JavaScriptここで trim を使っているのがポイントです。
” ” のようにスペースだけの入力も、空とみなして弾けます。
「入力 → 整形 → チェック → 処理」という流れを、
この小さな TODO でも意識しておくと、後で効いてきます。
追加後に入力欄をリセットする
ユーザーの動きを想像して仕上げる
タスクを追加したあと、入力欄に前の文字が残っていると、
「もう一回押したら同じタスクが増える」という事故が起きやすいです。
なので、追加後は入力欄を空にします。
addButtonElement.addEventListener("click", () => {
const text = taskInputElement.value.trim();
if (text === "") {
return;
}
const taskElement = document.createElement("p");
taskElement.textContent = text;
taskListElement.appendChild(taskElement);
taskInputElement.value = "";
});
JavaScriptこれで、
タスクを書く
追加ボタンを押す
一覧にタスクが増え、入力欄は空になる
という自然な流れになります。
「コードを書く」と同時に「使う人の動き」をイメージできると、一気にレベルが上がります。
関数分割で「タスク追加」を整理する
addTaskToList という役割を作る
今のコードは、まだイベントハンドラの中に処理が詰め込まれています。
Day21・Day24 でやったように、「役割ごとに関数に分ける」ことを意識してみましょう。
まず、「タスクを1つ画面に追加する処理」を関数にします。
function addTaskToList(text) {
const taskElement = document.createElement("p");
taskElement.textContent = text;
taskListElement.appendChild(taskElement);
}
JavaScriptこれを使ってイベントハンドラを書き直します。
addButtonElement.addEventListener("click", () => {
const text = taskInputElement.value.trim();
if (text === "") {
return;
}
addTaskToList(text);
taskInputElement.value = "";
});
JavaScriptこうすると、イベントハンドラは
入力値を取得する
空チェックをする
タスク追加関数を呼ぶ
入力欄をリセットする
という「流れ」だけを担当するようになります。
「画面にどう追加するか」の細かい話は addTaskToList に閉じ込められます。
この分け方は、後半で「削除機能」「完了チェック」「保存」などを足すときに、
あなたをかなり助けてくれます。
デバッグの視点も少しだけ入れておく
「動かない」ときにどこを見るか
もしここまで書いて、
ボタンを押しても何も起きない
タスクが表示されない
という状態になったら、Day22 のデバッグを思い出します。
イベントハンドラの最初に console.log を入れてみる。
addButtonElement.addEventListener("click", () => {
console.log("追加ボタンが押されました");
const text = taskInputElement.value.trim();
console.log("入力されたテキスト:", text);
if (text === "") {
console.log("空なので追加しません");
return;
}
addTaskToList(text);
taskInputElement.value = "";
});
JavaScriptこれで、
そもそもクリックイベントが発火しているか
入力値がちゃんと取れているか
if に引っかかって return していないか
を一つずつ確認できます。
「なんか動かない」ときに、
いきなりコードをいじるのではなく、
まず「何が起きているか」を観察する癖を、TODOアプリでも育てていきましょう。
Day25 前半の時点での完成コード
最小限の「タスク追加 TODO」
ここまでの内容をまとめると、前半の完成形はこうなります。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TODOアプリ</title>
</head>
<body>
<h1>TODOアプリ</h1>
<h2>タスク追加</h2>
<input id="taskInput" type="text" placeholder="やることを入力">
<button id="addButton">追加</button>
<h2>タスク一覧</h2>
<div id="taskList"></div>
<script>
const taskInputElement = document.getElementById("taskInput");
const addButtonElement = document.getElementById("addButton");
const taskListElement = document.getElementById("taskList");
function addTaskToList(text) {
const taskElement = document.createElement("p");
taskElement.textContent = text;
taskListElement.appendChild(taskElement);
}
addButtonElement.addEventListener("click", () => {
const text = taskInputElement.value.trim();
if (text === "") {
return;
}
addTaskToList(text);
taskInputElement.value = "";
});
</script>
</body>
</html>
まだ「削除」も「完了」も「保存」もありません。
でも、「タスクを追加して一覧に並べる」という TODO の一番コアな部分は、もう動いています。
Day25 前半のまとめ
前半でやったことを短く整理すると、こうです。
入力欄・ボタン・一覧エリアを HTML で用意した
DOM から要素を取得して、クリックイベントを設定した
タスクを p 要素として画面に追加する処理を書いた
空入力を弾き、追加後に入力欄をリセットするようにした
addTaskToList 関数で「タスク追加」の役割を分けた
後半では、この「タスク追加」を土台にして、
タスクを配列で管理する
後から削除や完了機能を足せる形にする
設計と実装をもう一段整理する
というところまで一緒に進めていきます。
