HTML/CSS/JavaScriptだけで、
ローカルストレージにタスクを保存するアプリです。
- タスクを入力して追加
- ページをリロードしても、前のタスクが残る(=保存された)
- ブラウザの「開発者ツール → Application → LocalStorage」で中身を確認できる
デモ
ソース
注意点
| 項目 | 内容 |
|---|---|
| 容量 | 数MB程度(ブラウザによる制限あり) |
| 共有 | 同じブラウザ・同じサイトでしか共有できない |
| 安全性 | JavaScriptから誰でも読める(パスワードなどはNG) |
| 速度 | 同期処理のため、大量データには不向き |
| 削除 | ユーザー操作や設定で削除されることもある |
LocalStorageとpostgresなどのバックエンドの違い
| 観点 | LocalStorage | サーバDB |
|---|---|---|
| 保存場所 | ブラウザ内 | サーバ側 |
| 利用範囲 | 自分のPCのブラウザのみ | すべてのユーザーで共有可能 |
| セキュリティ | 弱い(平文) | 強い(認証や暗号化可能) |
| 通信 | 不要(オフラインOK) | 必要(ネットワーク経由) |
どこかと通信してないか?という点、是非ブラウザの開発者ツール、ネットワークタブで確認してみましょう。
まとめ
- LocalStorage は「自分のブラウザに保存」する軽量な仕組み
- 小さなアプリや一時保存に便利
- ただし、本格的な共有や安全な保存にはバックエンドが必要
参考 ソース概要
各ファイルの概要
シンプルToDoアプリ 実装概要
1. index.html
このファイルは 画面構造(UIの骨組み) を担当します。
役割
HTMLはページの構造を定義します。
主な役割は次の通りです。
- アプリタイトル表示
- 新規タスク入力欄
- タスク追加ボタン
- フィルタボタン(すべて / 未完了 / 完了)
- 完了一括削除ボタン
- タスク一覧表示領域
- 未完了件数表示
主な構造
ヘッダー
アプリ名と説明文を表示します。
新規タスク入力エリア
ユーザーがタスクをid="newTaskInput" の入力欄に入力し、
id="addBtn" の「追加」ボタンで登録します。
ツールバー
タスク表示を切り替える「すべて / 未完了 / 完了」のフィルタボタンと、
「完了一括削除」ボタンがあります。
フィルタボタンには data-filter が付いていて、JS側がその値を見て切り替えます。
タスクリスト
ul#taskList は最初は空で、JavaScriptが動的に <li> 要素を生成して表示します。
フッター
leftCount に未完了件数を表示し、ダブルクリックで編集できるという使い方のヒントも表示しています。
2. style.css
このファイルは 見た目(デザイン) を担当します。
body では余白をなくし、フォントを指定し、暗めのグラデーション背景を設定しています。
container では最大幅、余白、背景、枠線、影を設定し、アプリ本体をカードのように見せています。
- ダークテーマ
- 中央カード型レイアウト
- モダンなボタンデザイン
- タスク行はグリッドレイアウト
デザイン構成
:root
色・影・角丸などのCSS変数を定義しています。
body
画面全体の背景グラデーションとフォント設定。
container
アプリ本体のカードUI。
入力エリア
入力欄と追加ボタンを横並び表示。
フィルタボタン
丸いピル型UIで、選択状態は .active で表現。
タスクリスト
task-list は縦並び、各 task-item は以下の3列グリッドです。
左にチェック、中央にタイトル、右に編集・削除ボタンを並べるため、grid-template-columns: 32px 1fr auto; にしています
チェックボックス | タイトル | 操作ボタン
完了タスクには .done クラスが付与され、
- 透明度低下
- 取り消し線
が適用されます。
レスポンシブ対応
画面幅が 480px 以下のとき、操作ボタンの間隔とサイズを少し詰めています。
つまり、スマホでも窮屈になりすぎないよう最低限の調整が入っています。
3. app.js
このファイルがアプリのロジック本体です。
ToDoの状態管理、localStorage保存、再描画、イベント処理を全部ここでやっています。
担当している処理
- タスク追加
- タスク削除
- 完了チェック
- フィルタ
- インライン編集
- localStorage保存
- UI再描画
3.1 状態管理
最初に LS_KEY でローカルストレージの保存キーを決めています。
アプリ状態は次の変数で管理されています。
tasks
currentFilter
taskの構造
{
id,
title,
done,
createdAt
}
以降で、HTML側で付けた id や class を使って、入力欄、追加ボタン、一覧領域、完了一括削除ボタン、未完了件数表示、フィルタボタン群を取得しています。
つまり、HTMLとJSはここで結び付いています。
3.2 localStorage管理
save()
タスク配列をJSONに変換して保存
localStorage.setItem()
load()
localStorageから読み込み
JSON.parse()
3.3 フィルタ処理
applyFilter()
現在のフィルタ状態に応じて
- 全件
- 未完了
- 完了
を切り替えます。
3.4 描画処理
render()
アプリのメイン処理です。
処理の流れ
- 一覧を空にする
- フィルタ適用
- タスクごとにDOM作成
- listへ追加
- 未完了数更新
3.5 タスク操作
追加
onAdd()
- 入力内容取得
- 新しいタスク作成
- 配列先頭へ追加
- 保存
- 再描画
削除
filter()
削除対象IDを除外して再生成。
完了チェック
チェックボックス変更時
task.done = true/false
3.6 インライン編集
タイトルをダブルクリックすると
span → input
に置き換えて編集可能になります。
| 操作 | 動作 |
|---|---|
| Enter | 保存 |
| Escape | キャンセル |
| blur | 保存 |
3.7 フィルタボタン
クリック時
currentFilter変更
→ render()
3.8 完了一括削除
完了済みタスクを
tasks = tasks.filter(t => !t.done)
で削除します。
3.9 初期化処理
ページロード時
- localStorageから読み込み
- render実行
- 入力欄フォーカス