0
0

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][L5] ボタン押下によりコンテンツ(div>ul>li)を別コンテンツ(div>ul>li)に移動(生成)する ([L4]で作成したコンポーネントを活用)

Last updated at Posted at 2024-11-20

実施条件

[JavaScript][L4] コンテンツ(div>ul>li)の生成機能を共通化(コンポーネント化)するを理解していること

環境

MacBook Pro (2.3 GHz 8コアIntel Core i9)
macOS 14.0(23A344)
Homebrew 4.3.8
gh 2.52.0

ソースコード外観

HTML

index.html
<!DOCTYPE html>
<html>
  <head>
    <title>TODO(JS)</title>
    <meta charset="UTF-8" />
  </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">
        <!--  // 完成系の例としてliタグ以下を作成している
        <li>
          <div class="list-row">
            <p class="todo-item">TODOです</p>
            <button>完了</button>
            <button>削除</button>
          </div>
        </li> -->
      </ul>
    </div>
    <div class="complete-area">
      <p class="title">完了したTODO</p>
      <ul id="complete-list">
        <!--  // 完成系の例としてliタグ以下を作成している
        <li>
          <div class="list-row">
            <p class="todo-item">TODOでした</p>
            <button>戻す</button>
          </div>
        </li> -->
      </ul>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

JavaScript

index.js
import "./styles.css";

const onClickAdd = () => {
  // テキストボックスの値を取得し、初期化する
  const inputText = document.getElementById("add-text").value;
  document.getElementById("add-text").value = "";
  
  // 未完了リストに追加
  createIncompleteTodo(inputText);
  };

// 渡された引数を基に未完了のTODOを作成する関数
const createIncompleteTodo = (todo) => {
  // li生成
  const li = document.createElement("li");

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

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

  // button(完了)タグ生成
  const completeButton = document.createElement("button");
  completeButton.innerText = "完了";
  completeButton.addEventListener("click", () => {
    // 押された完了ボタンの親にあるliタグ配下の完了ボタンと削除ボタンを削除
    const moveTarget = completeButton.closest("li");
    completeButton.nextElementSibling.remove();
    completeButton.remove();
    // 戻すボタンを生成してdivタグ配下に設定
    const backButton = document.createElement("button");
    backButton.innerText = "戻す";
    backButton.addEventListener("click", () => {
      // TODOの内容を取得し、未完了リストに追加
      const todoText = backButton.previousElementSibling.innerText;
      createIncompleteTodo(todoText);
      // 押された戻すボタンの親にあるliタグを削除
      backButton.closest("li").remove();
    });
    moveTarget.firstElementChild.appendChild(backButton);
    // 完了リストに移動
    document.getElementById("complete-list").appendChild(moveTarget);
  });

  // button(削除)タグ生成
  const deleteButton = document.createElement("button");
  deleteButton.innerText = "削除";
  deleteButton.addEventListener("click", () => {
    // 押された削除ボタンの親にあるliタグを未完了リストから削除
    const deleteTarget = deleteButton.closest("li");
    document.getElementById("incomplete-list").removeChild(deleteTarget);
  });

  // liタグの子要素に各要素を設定
  div.appendChild(p);
  div.appendChild(completeButton);
  div.appendChild(deleteButton);
  li.appendChild(div);

  // id="incomplete-list"の`ul`タグに子要素を設定した`li`タグを追加
  document.getElementById("incomplete-list").appendChild(li);    
  };

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

手順

  1. 戻すボタン(backButton)が押された際に呼び出す関数を用意する
    index.js
      // button(完了)タグ生成
      const completeButton = document.createElement("button");
      completeButton.innerText = "完了";
      completeButton.addEventListener("click", () => {
        // 押された完了ボタンの親にあるliタグ配下の完了ボタンと削除ボタンを削除
        const moveTarget = completeButton.closest("li");
        completeButton.nextElementSibling.remove();
        completeButton.remove();
        // 戻すボタンを生成してdivタグ配下に設定
        const backButton = document.createElement("button");
        backButton.innerText = "戻す";
    +   backButton.addEventListener("click", () => {
    +   });
        moveTarget.firstElementChild.appendChild(backButton);
        // 完了リストに移動
        document.getElementById("complete-list").appendChild(moveTarget);
      });
    
  2. TODOの内容を取得し、未完了リストに追加する
    previousElementSiblingnextElementSiblingの逆で、HTMLの前(コードで上では上部)の要素を指す
    index.js
      // button(完了)タグ生成
      const completeButton = document.createElement("button");
      completeButton.innerText = "完了";
      completeButton.addEventListener("click", () => {
        // 押された完了ボタンの親にあるliタグ配下の完了ボタンと削除ボタンを削除
        const moveTarget = completeButton.closest("li");
        completeButton.nextElementSibling.remove();
        completeButton.remove();
        // 戻すボタンを生成してdivタグ配下に設定
        const backButton = document.createElement("button");
        backButton.innerText = "戻す";
        backButton.addEventListener("click", () => {
    +     // TODOの内容を取得し、未完了リストに追加
    +     const todoText = backButton.previousElementSibling.innerText;
    +     createIncompleteTodo(todoText);
        });
        moveTarget.firstElementChild.appendChild(backButton);
        // 完了リストに移動
        document.getElementById("complete-list").appendChild(moveTarget);
      });
    
  3. 押された戻すボタンの親にあるliタグを削除
    index.js
      // button(完了)タグ生成
      const completeButton = document.createElement("button");
      completeButton.innerText = "完了";
      completeButton.addEventListener("click", () => {
        // 押された完了ボタンの親にあるliタグ配下の完了ボタンと削除ボタンを削除
        const moveTarget = completeButton.closest("li");
        completeButton.nextElementSibling.remove();
        completeButton.remove();
        // 戻すボタンを生成してdivタグ配下に設定
        const backButton = document.createElement("button");
        backButton.innerText = "戻す";
        backButton.addEventListener("click", () => {
          // TODOの内容を取得し、未完了リストに追加
          const todoText = backButton.previousElementSibling.innerText;
          createIncompleteTodo(todoText);
    +     // 押された戻すボタンの親にあるliタグを削除
    +     backButton.closest("li").remove();
        });
        moveTarget.firstElementChild.appendChild(backButton);
        // 完了リストに移動
        document.getElementById("complete-list").appendChild(moveTarget);
      });
    

Tips

戻す buttonタグから見ると、pタグがpreviousElementSibling

index.html
        <li>
          <div class="list-row">
            <p class="todo-item">TODOでした</p>
            <button>戻す</button>
          </div>
        </li>

完了 buttonタグから見ると、削除 buttonタグがnextElementSibling

index.html
        <li>
          <div class="list-row">
            <p class="todo-item">TODOです</p>
            <button>完了</button>
            <button>削除</button>
          </div>
        </li>

参考リンク

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?