簡単なTODOアプリケーション

# 初めに

HTML、CSS、JavaScript で作る簡単な TODO アプリケーションです。
https://www.youtube.com/watch?v=E08jeQBa1D0&t=3677s
の動画を見て学習していた時に書いていたので、まんまそのままっぽいです。
（怒らないでね。@_@♪）

# ひとまずコード

```html:index.html
<!DOCTYPE html>
<html lang="en">
<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>
    <h1 class="title">TODO</h1>
    <form action="" id="form">
        <input type="text" class="list" id="input" autocomplete="off" placeholder="Enter TODO here">
    </form>
    <br>
    <ul id="list-container" style="padding-left: 0;"></ul>
    <!-- ulタグは左に余白できるから、"padding-left: 0;"を設定しときます。-->
    <script src="script.js"></script>
</body>
</html>
````

```css:style.css
.title {
    text-align: center;
    /* タイトルテキストを真ん中に配置 */
}

.list {
    list-style: none;
    /* li要素にはデフォルトでlist-styleがついちゃうから、消す */
    display: block;
    /* これはinputタグ用 */
    padding-left: 10px;
    /* 見やすくなる気がするので、左に余白 */
    width: 450px; /* 幅 */
    height: 20px; /* 高さ */
    border: none;
    /* inputタグには元々borderがつくからひとまず消す */
    border-bottom: solid 1px;
    /* で、下にのみ枠線ひく */
    margin: 3px auto; /* 真ん中、上の要素から3px下で配置 */
}

.line {
    text-decoration-line: line-through;
    /* 単純にテキストに取り消し線を入れる */
    text-align: end; /* テキスト位置を後ろにする */
}
````

```javascript:script.js
const input = document.getElementById('input');
// inputタグを習得

const todos = JSON.parse(localStorage.getItem('todos'));
// 保存しているデータ（ローカルストレージ内の）を取得
// 参考：https://developer.mozilla.org/ja/docs/Web/API/Window/localStorage

// もしもローカルストレージにデータがありましたらば
if (todos) {
    todos.forEach((todo) => {
        add(todo);
    });
}

// formタグを習得、そしてイベント処理（"submit"は「エンター」）
document.getElementById('form').addEventListener('submit', (e) => {
    // エンター押されるとページがリロードされちゃうから、preventDefault();
    e.preventDefault();
    add();
});

// todoを追加する関数
function add(todo)
{
    // inputタグ内のテキストを取得
    let todotext = input.value;
    // もし引数として取ってるtodoがありましたらば（ローカルストレージの時しか渡してない）
    if (todo) {
        todotext = todo.text;
    }

    // まぁひとまず、なにかしらがございましたら
    // todotext.trim()で、スペースのみの場合も処理しないようにする（初投稿ではこの機能は書いていません。親切な方に改善案を頂きました。）-A-
    if (todotext.trim()) {
        // li要素を作成
        const list = document.createElement('li');
        // テキスト入れる
        list.innerText = todotext;
        // そんでクラス指定する
        list.classList.add('list');

        // 保存されたtodoのクラスにline（取り消し線）が含まれていたらば
        if (todo && todo.class) {
            // クラスにlineを追加
            list.classList.add('line');
        }

        // listが右クリック（contextmenu）された時
        list.addEventListener('contextmenu', (e) => {
            // いろいろ出てくるから、でないようにpreventDefault();
            e.preventDefault();
            // list要素を削除
            list.remove();
            // 保存
            saver();
        });

        list.addEventListener('click', () => {
            // listのクラスにlineがあれば消し、なければ加える
            list.classList.toggle('line');
            // 保存
            saver();
        });

        // ulタグを取得、そこの子要素としてlistを加える
        document.getElementById('list-container').appendChild(list);
        // 保存
        saver();
    }
    // -A-より、スペースのみであった場合、それを消す必要があるので、ここでinput.value = ""にする。
    input.value = "";
}

function saver()
{
    // 保存するデータを入れる大元の配列を作成
    let todos = [];
    // li要素をすべて取得、それぞれに対して処理（forEach文）
    document.querySelectorAll('li').forEach((list) => {
        // todoデータ作成
        const todo = {
            // todo.textとして、li要素内のテキストを取得
            text: list.innerText,
            // li要素に取り消し線が引かれてるかを取得（containsはtrue or falseを返す）
            class: list.classList.contains('line')
        };
        // todosにtodoを
        todos.push(todo);
    });
    // ローカルストレージにデータを保存
    localStorage.setItem('todos', JSON.stringify(todos));
}
````

# 最後に
こんなんになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674822/48eb2681-eae7-3c81-05b1-7b09d30e4353.png)