1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptで簡易的TODOアプリの作成 学習振り返り

Last updated at Posted at 2024-03-27

TODOアプリの作成の準備

  • 下記の構造でファイルを作成
  TODO
    ├── index.html
    ├── index.js
    └── style.css  

HTMLで構造を作成する(マークアップ)

index.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>
        <input placeholder="TODOを入力">
        <button>追加</button>
    </div>

    <div>
        <p>予定のTODO</p>
        <ul>
            <li>
                <div>
                    <p>勉強会</p>
                    <button>完了</button>
                    <button>削除</button>
                </div>
            </li>
        </ul>
    </div>

    <div>
        <p>完了したTODO</p>
        <ul>
            <li>
                <div>
                    <p>飲み会</p>
                    <button>戻す</button>
                </div>
            </li>
        </ul>
    </div>

    <script src="./index.js"></script>
</body>

</html>

CSSでスタイリング

  • まずは index.html に class を付与
index.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="input-area">
        <input placeholder="TODOを入力">
        <button>追加</button>
    </div>

    <div class="incomplete-area">
        <p class="title">予定のTODO</p>
        <ul>
            <li>
                <div class="list-row">
                    <p class="todo-item">勉強会</p>
                    <button>完了</button>
                    <button>削除</button>
                </div>
            </li>
            <li>
                <div class="list-row">
                    <p class="todo-item">勉強会</p>
                    <button>完了</button>
                    <button>削除</button>
                </div>
            </li>
        </ul>
    </div>

    <div class="complete-area">
        <p class="title">完了したTODO</p>
        <ul>
            <li>
                <div class="list-row">
                    <p class="todo-item">飲み会</p>
                    <button>戻す</button>
                </div>
            </li>
            <li>
                <div class="list-row">
                    <p class="todo-item">飲み会</p>
                    <button>戻す</button>
                </div>
            </li>
        </ul>
    </div>
    
    <script src="./index.js"></script>
</body>

</html>
  • styles.css を編集
styles.css
body {
  font-family: sans-serif;
  color: #666;
}

input {
  border-radius: 8px;
  border: none;
  padding: 6px 16px;
}

button {
  border-radius: 8px;
  border: none;
  padding: 4px 16px;
  margin: 0px 2px;
}

button:hover {
  background-color: #79a8a9;
  color: #fff;
  cursor: pointer;
}

.input-area {
  background-color: #c6e5d9;
  width: 400px;
  height: 30px;
  padding: 8px;
  margin: 8px;
  border-radius: 8px;
}

.incomplete-area {
  border: 2px solid #aacfd0;
  width: 400px;
  min-height: 200px;
  padding: 8px;
  margin: 8px;
  border-radius: 8px;
}

.complete-area {
  border: 2px solid #aacfd0;
  width: 400px;
  min-height: 200px;
  padding: 8px;
  margin: 8px;
  border-radius: 8px;
  background-color: #c9dede;
}

.title {
  text-align: center;
  margin-top: 0;
  font-weight: bold;
}

.list-row {
  display: flex;
  align-items: center;
}

.todo-item {
  margin: 6px;
}

タスクの追加機能を実装していく

index.htmlを編集

  • 追加ボタンに idを付与 (id="add-button")
index.html
<!-- 省略 -->

<body>
    <div class="input-area">
        <input placeholder="TODOを入力">
        <button id="add-button">追加</button>
    </div>

    <!-- 省略 -->

</body>

 <!-- 省略 -->

index.jsを編集

  • id="add-button"のある 追加ボタンをクリックしたらアラートがでるようにする。(onClickAdd関数が動作するかどうかの確認)
index.js
'use strict';

const onClickAdd = () => {
    alert();
}

document.getElementById('add-button').addEventListener('click', onClickAdd);

追加ボタンをクリックしてアラートがでるか試してみる。

  • TODOを入力して 追加 ボタンをクリックするとアラートに追加したTODOが表示されるか試してみる(onClickAdd関数の実行時)。

  • class="input-area"inputid="add-text"を付与する。

index.htmlを編集

index.html
<!-- 省略 -->

<body>
    <div class="input-area">
        <input id="add-text" placeholder="TODOを入力">
        <button id="add-button">追加</button>
    </div>

    <!-- 省略 -->

</body>

 <!-- 省略 -->

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    // 入力したTODOを const inputText に格納
    const inputText = document.getElementById('add-text').value;
    alert(inputText);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);

何か入力して 追加ボタン押下時にアラートテキストが出力されるか確認。

  • 追加後は テキストボックスにテキストが残らないようにするため、valueを空にする(初期化)。

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    // 追加した後にテキストボックスを空白にして初期化する
    document.getElementById('add-text').value = '';
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
  • index.jsliタグを生成する。

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    // liタグの生成
    const li = document.createElement("li");
    console.log(li); // TODO追加後に生成されているかどうか確認
}

document.getElementById('add-button').addEventListener('click', onClickAdd);

TODO追加後はコンソールを確認

console
<li></li>
  • 続いて div タグの生成

index.jsに追加

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    // divタグの生成
    const div = document.createElement("div");
    console.log(div);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);

同じくコンソールを確認

console
<div></div>
  • divタグに class="list-row" を付ける

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row"; // divにclass="list-row"を付ける
    console.log(div);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
console
<div class="list-row"></div>
  • pタグを生成
  • pタグには todo-itemクラスを付ける
  • pタグには追加されたTODOが入るようにする(定数 inputTextに追加するTODOが入る)

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    // pタグの生成
    const p = document.createElement("p");
    // pタグにclass="todo-item"を付ける
    p.className = "todo-item";
    // pタグに追加されたTODOを入れる
    p.innerText = inputText;
    console.log(p);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
console
<p class="todo-item">hoge</p>
  • <div class="list-row"> の子要素に <p class="todo-item"></p>を配置する。

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = inputText;

    // divタグの子要素にpタグを配置
    div.appendChild(p);
    console.log(div);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
console
<div class="list-row">
    <p class="todo-item">hoge</p>
</div>
  • liタグの子要素に<div class="list-row>を配置する

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = inputText;

    div.appendChild(p);

    // liタグの子要素にdivを配置
    li.appendChild(div);
    console.log(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
console
<li>
  <div class="list-row">
    <p class="todo-item">hoge</p>
  </div>
</li>
  • incomplete-area内の ulタグに id="incomplete-list"を付与する

index.htmlを編集

index.html
<!-- 省略 -->

    <div class="incomplete-area">
        <p class="title">予定のTODO</p>
        <ul id="incomplete-list"> <!-- id="incomplete-list"の付与 -->
            <li>
                <div class="list-row">
                    <p class="todo-item">勉強会</p>
                    <button>完了</button>
                    <button>削除</button>
                </div>
            </li>
            <li>
                <div class="list-row">
                    <p class="todo-item">勉強会</p>
                    <button>完了</button>
                    <button>削除</button>
                </div>
            </li>
        </ul>
    </div>

    <!-- 以下省略 -->
  • <ul id="incomlete-list">の子要素にliタグを配置する(未完了リストに追加)。

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = inputText;

    div.appendChild(p);

    li.appendChild(div);

    // idがincomlete-listの子要素にliタグを入れる(未完了リストに追加)
    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);

これで、ブラウザに追加したTODOが表示される。

TODOの完了ボタンと削除ボタンの生成

  • 完了ボタンの生成

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = inputText;

    // button(完了)ボタンの生成
    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    console.log(completeButton);

    div.appendChild(p);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
console
<button>完了</button>
  • 削除ボタンの生成

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = inputText;

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";

    // button(削除)ボタンの生成
    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    console.log(deleteButton);

    div.appendChild(p);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
console
<button>削除</button>
  • divタグ(incomplete-list内) の子要素に完了ボタンと削除ボタンを配置する。

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = inputText;

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";

    // 順番通りに。。。
    div.appendChild(p);
    div.appendChild(completeButton); // 完了ボタンをdivの子要素に配置
    div.appendChild(deleteButton); // 削除ボタンをdivの子要素に配置

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);

これで何かTodo追加時に完了ボタンと削除ボタンがブラウザで表示される。

TODOの削除機能を作成

  • 削除ボタンと完了ボタンにaddEventListenerの適用

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = inputText;

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    // addEventListenerの適用
    completeButton.addEventListener('click', () => {
        alert("完了"); // 完了ボタン押下時の処理
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        alert("削除"); // 削除ボタンを押下時の処理
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);

完了ボタン及び削除ボタンをクリックするとアラートがでる(テスト)。

  • TODOを削除する際は、liタグから削除されるようにする closestを使用すると良い。
    (削除ボタンの親にあるliタグから拾う)

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = inputText;

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        alert("完了");
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        // 削除ボタンの親にあるliから要素を拾う
        // deleteTargetには削除する要素が入っている
        const deleteTarget = deleteButton.closest("li"); 
        console.log(deleteTarget);
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);

下記が削除したい要素になる

console
<li>
  <div class="list-row">
    <p class="todo-item">hoge</p>
    <button>完了</button>
  </div>
</li>

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';

    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = inputText;

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        alert("完了");
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        const deleteTarget = deleteButton.closest("li");
        // deleteTargetは<ul id="incomplete-list">の子要素になるため removeChildメソッドにdeleteTargetを指定して上げればよい
        document.getElementById('incomplete-list').removeChild(deleteTarget);
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);

これでTODOは削除可能になる。

TODOの完了機能を作成

  • 完了ボタン押下時のプロセス
  1. 完了ボタン押下するとcomplete-areaの方へ移動するようになるので、その要素を選択するようにする。
  2. 削除ボタンが削除される
    ( nextElementSiblingメソッドを使い完了ボタン要素の次に続く兄弟要素ノードを選択できる。つまり、ボタンの直後に存在するHTML要素を取得して、それをremoveメソッドで削除ボタンを削除できる)
  3. 完了ボタンが削除される
    (単純にcompleteButtonremoveメソッドを使って削除すればよい)

完了ボタンを押下時に削除ボタンが消えるようにする

index.jsを編集

index.js
    // 省略

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        // completeエリアに移動する要素を選択
        const moveTarget = completeButton.closest("li");
        // 完了ボタンの兄弟要素の削除ボタンを選択し、削除する
        completeButton.nextElementSibling.remove();
        // 完了ボタンを削除
        completeButton.remove();
    });

    // 以下省略

これで完了ボタンを押下すると削除ボタンと完了ボタンは削除される。

完了ボタン押下後に戻すボタンが追加されるようにする

  • moveTargetの要素の初めの子要素(div)の子要素に戻すボタンを追加するようにするには firstElementChildメソッドとappendChildメソッドを繋げるようにする。

index.jsを編集

index.js
    // 省略

        const completeButton = document.createElement("button");
        completeButton.innerText = "完了";
        completeButton.addEventListener('click', () => {
          const moveTarget = completeButton.closest("li");
          completeButton.nextElementSibling.remove();
          completeButton.remove();
          // ボタン要素の作成
          const backButton = document.createElement("button");
          // ボタン要素にテキスト '戻す'を設定
          backButton.innerText = "戻す";
          // moveTarget(li要素)の子要素(div)のさらに子要素に'戻す'ボタンを追加
          moveTarget.firstElementChild.appendChild(backButton);
    });

  // 以下省略

これで完了ボタンを押下すると 戻すボタンが追加される

完了したTODOエリア(complete-area)に移動する

  1. htmlcomplete-areaulタグにid="complete-list"を付与する。
  2. moveTarget<ul id="complete-list">の子要素に配置する。
index.html
      <!-- 省略 -->

    <div class="complete-area">
        <p class="title">完了したTODO</p>
        <ul id="complete-list"> <!-- id="complete-list"を付与 -->
            <li>
                <div class="list-row">
                    <p class="todo-item">飲み会</p>
                    <button>戻す</button>
                </div>
            </li>
            <li>
                <div class="list-row">
                    <p class="todo-item">飲み会</p>
                    <button>戻す</button>
                </div>
            </li>
        </ul>
    </div>

    <!-- 以下省略 -->
  • moveTargetid="complete-list"の子要素に移動

index.jsを編集

index.js
    // 省略

        const completeButton = document.createElement("button");
        completeButton.innerText = "完了";
        completeButton.addEventListener('click', () => {
          const moveTarget = completeButton.closest("li");
          completeButton.nextElementSibling.remove();
          completeButton.remove();
          const backButton = document.createElement("button");
          backButton.innerText = "戻す";
          moveTarget.firstElementChild.appendChild(backButton);
          // complete-listの子要素に moveTargetを移動
          document.getElementById("complete-list").appendChild(moveTarget);
    });

    // 以下省略

これで 完了ボタンを押下すると完了したTODOのリストに移動する

完了したTODOを予定のTODOへ戻す機能の実装

  1. createIncompleteTodo関数を作成して渡された引数を基に未完了のTODOを作成する機能を実装します。

  2. 下記のindex.jsの 下記のコードの部分を createImcompleteTodo関数の中に移動します。

  3. onClickAdd関数の中の 定数 inputTextcreateIncompleteTodoに送るようにしなくてはならないので、onClickAdd関数の中に createIncompleteTodo関数を実行させる記述が必要になります。

index.js
// 下記の部分のコードをcreateImcompleteTodo関数を作成して、その中に移動する
    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = inputText;

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        const moveTarget = completeButton.closest("li");
        completeButton.nextElementSibling.remove();
        completeButton.remove();
        const backButton = document.createElement("button");
        backButton.innerText = "戻す";
        moveTarget.firstElementChild.appendChild(backButton);
        document.getElementById("complete-list").appendChild(moveTarget);
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        const deleteTarget = deleteButton.closest("li");
        document.getElementById('incomplete-list').removeChild(deleteTarget);
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';
    // inputTextをcreateIncompleteTodo関数に送る
    createIncompleteTodo(inputText);
}

// 渡された引数を基に未完了のTODOを作成する関数
const createIncompleteTodo = (todo) => {
    // ここから移動してきたコード
    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    // inputTextはtodoの引数に入ってくるので todo に変更する
    p.innerText = todo;

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        const moveTarget = completeButton.closest("li");
        completeButton.nextElementSibling.remove();
        completeButton.remove();
        const backButton = document.createElement("button");
        backButton.innerText = "戻す";
        moveTarget.firstElementChild.appendChild(backButton);
        document.getElementById("complete-list").appendChild(moveTarget);
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        const deleteTarget = deleteButton.closest("li");
        document.getElementById('incomplete-list').removeChild(deleteTarget);
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
    // ここまで
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
  1. 戻すボタンをクリックした時のaddEventListenerを追加します。

index.jsを編集

index.js
'use strict';

const onClickAdd = () => {
    const inputText = document.getElementById('add-text').value;
    document.getElementById('add-text').value = '';
    createIncompleteTodo(inputText);
}

const createIncompleteTodo = (todo) => {
    const li = document.createElement("li");

    const div = document.createElement("div");
    div.className = "list-row";

    const p = document.createElement("p");
    p.className = "todo-item";
    p.innerText = todo;

    const completeButton = document.createElement("button");
    completeButton.innerText = "完了";
    completeButton.addEventListener('click', () => {
        const moveTarget = completeButton.closest("li");
        completeButton.nextElementSibling.remove();
        completeButton.remove();
        const backButton = document.createElement("button");
        backButton.innerText = "戻す";

        // 戻すボタンのイベントリスナーを追加
        backButton.addEventListener("click", () => {
            alert();
        });

        moveTarget.firstElementChild.appendChild(backButton);
        document.getElementById("complete-list").appendChild(moveTarget);
    });

    const deleteButton = document.createElement("button");
    deleteButton.innerText = "削除";
    deleteButton.addEventListener('click', () => {
        const deleteTarget = deleteButton.closest("li");
        document.getElementById('incomplete-list').removeChild(deleteTarget);
    });

    div.appendChild(p);
    div.appendChild(completeButton);
    div.appendChild(deleteButton);

    li.appendChild(div);

    document.getElementById("incomplete-list").appendChild(li);
}

document.getElementById('add-button').addEventListener('click', onClickAdd);
  • 戻すボタンのイベントリスナーの中の処理内容
  1. previousElementSiblingメソッドを使って buckButton の一個手前に要素(pタグになる)を参照してinnerTextメソッドでテキストだけを取得する。
  2. createIncompleteTodo関数の引数にそのテキストを入れるようにして実行させる
    (予定のTODOのリストに追加される)
  3. まだ戻すボタンを押下しても完了したTODOに残ってるのでそれを削除するようにする

index.jsを編集

index.js
   // 省略

         backButton.addEventListener("click", () => {
               // backbutton.previousElementSiblingはbuckButtonの一個手前に要素(pタグになる)を参照してinnerTextでテキストだけを取得する
            const todoText = backButton.previousElementSibling.innerText;
            // createIncompleteTodoの引数にtodoTextを入れて実行
            createIncompleteTodo(todoText);
            // 完了したTODOに戻したTODOが残ってしまうので削除する
            backButton.closest("li").remove();
        });

  // 以下省略

以上で 戻す機能の実装は終了です。

後は以下のように index.htmlli要素ノードを消しておけばOKです。

index.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="input-area">
        <input id="add-text" placeholder="TODOを入力">
        <button id="add-button">追加</button>
    </div>

    <div class="incomplete-area">
        <p class="title">予定のTODO</p>
        <ul id="incomplete-list">
        </ul>
    </div>

    <div class="complete-area">
        <p class="title">完了したTODO</p>
        <ul id="complete-list">
        </ul>
    </div>

    <script src="./index.js"></script>
</body>

</html>

JavaScriptだけでこのようなアプリを作成するとなるとこんなに複雑になるのですね。
仕組みはよく理解できました。

1
2
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?