質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1472閲覧

todo list 削除ボタンを押したら、その指定の要素を削除するを実装したい

penny271

総合スコア9

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/07/20 12:04

前提・実現したいこと

Todoリストを作成しています。
削除ボタンを押したときに押したボタンと同じ行の要素を削除したいです。

しかし、現状、例えばID 2の行の削除ボタンを押すと、一番上の要素(ID 0の行)が削除され、ID 2の行が削除されません。どのボタンを押しても一番上の要素が削除される仕様となっています。

発生している問題・エラーメッセージ

ディベロッパーツールのconsoleを見ても特にエラーメッセージは表示されていません。

なし

該当のソースコード(問題と思われる部分の抜粋)

JavaScript

1 conditionDeleteTd.addEventListener('click', () => { 2 //どのindexの削除ボタンが押されたかを確認するためそのindexを取得 3 4 let each = tasks.forEach((taskEach, index) => { 5 return index; 6 }); 7 8 console.log(each); //!デバッグ用 9 10 //削除ボタンを押された配列を削除 11 tasks.splice(each, 1); 12 13 //配列の要素を削除した後で再表示 14 displayTasks(); 15 }); 16

該当のソースコード(全文)

javascript

1'use strict'; 2 3{ 4 const addTaskTrigger = document.getElementById('addBtn'); 5 const addTaskTarget = document.getElementById('addTaskTarget'); 6 const input = document.getElementById('input'); 7 8 let idNum = 0; 9 10 let tasks = []; 11 //追加ボタンクリック時の詳細な挙動 12 const addTask = () => { 13 let task = { 14 id: idNum, 15 comment: input.value, 16 }; 17 18 tasks.push(task); 19 20 //結果ブラウザ上に表示させる 21 displayTasks(); 22 }; 23 24 //todoのタスクを作成及び結果をブラウザに表示 25 const displayTasks = () => { 26 //¥初期化処理 - ここでブラウザに表示されるtrを 27 //¥全て削除することで画面上タスクを見えなくする 28 document.querySelectorAll('.addedTr').forEach((tr) => { 29 tr.remove(); 30 }); 31 tasks.forEach((each, index) => { 32 const tr = document.createElement('tr'); 33 tr.classList.add('addedTr'); 34 const idTd = document.createElement('td'); 35 const commentTd = document.createElement('td'); 36 const conditionWorkingTd = document.createElement('td'); 37 const conditionDeleteTd = document.createElement('td'); 38 conditionWorkingTd.className = 'btn'; 39 conditionDeleteTd.className = 'btn'; 40 41 addTaskTarget.appendChild(tr); 42 tr.appendChild(idTd); // 1つめ 43 // idTd.textContent = tasks[index].id; 44 idTd.textContent = index; 45 tr.appendChild(commentTd); // 2つ目 46 commentTd.textContent = tasks[index].comment; // タスク入力値 47 tr.appendChild(conditionWorkingTd); // 3つ目 48 conditionWorkingTd.textContent = '作業中'; 49 tr.appendChild(conditionDeleteTd); // 4つ目 50 conditionDeleteTd.textContent = '削除'; 51 52 //¥削除機能:削除ボタンが押された時に押された要素を削除する 53 conditionDeleteTd.addEventListener('click', () => { 54 //どのindexの削除ボタンが押されたかを確認するためそのindexを取得 55 56 let each = tasks.forEach((taskEach, index) => { 57 return index; 58 }); 59 60 console.log(each); //!デバッグ用 61 62 //削除ボタンを押された配列を削除 63 tasks.splice(each, 1); 64 65 //配列の要素を削除した後で再表示 66 displayTasks(); 67 }); 68 }); 69 console.log(tasks); //!デバッグ用 70 }; 71 72 //追加ボタンクリック時にaddTask()を走らせる 73 addTaskTrigger.addEventListener('click', () => { 74 addTask(); 75 input.value = ''; 76 }); 77} 78

該当のソースコード(参考)

html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8" /> 5 <title>todolist練習</title> 6 <link rel="stylesheet" href="css/styles.css" /> 7 </head> 8 <body> 9 <h1>ToDoリスト</h1> 10 <div class="radios"> 11 <input type="radio" name="rdo" checked />すべて 12 <input type="radio" name="rdo" />作業中 13 <input type="radio" name="rdo" />完了 14 </div> 15 16 <div> 17 <table> 18 <!-- テーブルヘッダー --> 19 <thead> 20 <tr> 21 <th>ID</th> 22 <th>コメント</th> 23 <th>状態</th> 24 </tr> 25 </thead> 26 <tbody id="addTaskTarget"> 27 <!-- 実装されたイメージを持つために以下を一時的に作成 --> 28 <!-- <tr> 29 <td>0</td> 30 <td>aaa</td> 31 <td id="working" class="btn">作業中</td> 32 <td id="remove" class="btn">削除</td> 33 </tr> --> 34 <!-- [1] ここに <tr> で ToDo の要素を表示したい --> 35 </tbody> 36 </table> 37 </div> 38 39 <h2> 40 新規タスクの追加 41 </h2> 42 <input id="input" type="text" size="29" /> 43 44 <button id="addBtn" class="btn">追加</button> 45 <script src="main.js"></script> 46 </body> 47</html> 48

該当のソースコード(参考)

css

1.radios { 2 margin: 0; 3 padding: 0; 4} 5 6input { 7 margin: 0 5px 0 0; 8} 9 10.btn { 11 border: 1px solid #c4c3c3; 12 border-radius: 5px; 13 padding: 0 7px; 14 font-size: 12px; 15 background-color: #fff; 16 height: 20px; 17} 18 19.btn { 20 border: 1px solid #c4c3c3; 21 border-radius: 5px; 22 padding: 0 7px; 23 font-size: 12px; 24 background-color: #fff; 25 height: 20px; 26} 27 28.btn_2 { 29 border: 1px solid #c4c3c3; 30 border-radius: 5px; 31 padding: 0 7px; 32 font-size: 12px; 33 background-color: #fff; 34 height: 20px; 35} 36 37.btn:hover { 38 background-color: #2a4bcb; 39 color: #fff; 40} 41 42ul { 43 margin: 0; 44 padding: 0; 45} 46 47li { 48 list-style: none; 49} 50

試したこと

splice()を使うことで配列の任意の位置の要素を削除できることを見つけ実装しました。
該当のソースコード(問題と思われる部分の抜粋)の中のconsole.log(each)を実行するとundefinedと返ってきますので
conditionDeleteTd.addEventListener('click', () => { //どのindexの削除ボタンが押されたかを確認するためそのindexを取得 let each = tasks.forEach((taskEach, index) => { return index; }); console.log(each); //!デバッグ用 ← ここでundefinedと返される //削除ボタンを押された配列を削除 tasks.splice(each, 1);
の記述が間違っているものと思われるところまでわかりました。
その後はググってみましたが、自力で実装方法を見つけることができませんでした。

どうやったら、複数ある削除ボタンから特定の削除ボタンが押されたら、それがtasksの中のどの配列のindexかを認識させられるかわかれば実装できるかと思いますが、その方法がわかりません。

どういう考え方で実装していけばいいのか、ヒントや実装方法を教えていただけないでしょうか。
どうぞよろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

エディタ:Visual Stadio Code
プログラミング初心者です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ソースコードを読んでも初心者の私の知識では読むことが難しいコードでしたので、
読むのを諦めてほぼ初めからコードを書いてちゃんと動作するようにしました。
面倒なのでHTMLにcssとJavascript合わせて書いていますのでコピペで完全動作します。
参考になれば幸いです。

HTML

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8" /> 6 <title>todolist練習</title> 7 <style> 8 .radios { 9 margin: 0; 10 padding: 0; 11 } 12 13 input { 14 margin: 0 5px 0 0; 15 } 16 17 .btn { 18 border: 1px solid #c4c3c3; 19 border-radius: 5px; 20 padding: 0 7px; 21 font-size: 12px; 22 background-color: #fff; 23 height: 20px; 24 } 25 26 .btn:hover { 27 background-color: #2a4bcb; 28 color: #fff; 29 } 30 31 ul { 32 margin: 0; 33 padding: 0; 34 } 35 36 li { 37 list-style: none; 38 } 39 </style> 40</head> 41 42<body> 43 <h1>ToDoリスト</h1> 44 <div class="radios"> 45 <input type="radio" name="rdo" checked />すべて 46 <input type="radio" name="rdo" />作業中 47 <input type="radio" name="rdo" />完了 48 </div> 49 50 <div> 51 <table> 52 <!-- テーブルヘッダー --> 53 <thead> 54 <tr> 55 <th>ID</th> 56 <th>コメント</th> 57 <th>状態</th> 58 </tr> 59 </thead> 60 <tbody id="addTaskTarget"></tbody> 61 </table> 62 </div> 63 <h2> 64 新規タスクの追加 65 </h2> 66 <input id="input" type="text" size="29" /> 67 68 <button id="addBtn" class="btn">追加</button> 69 <script> 70 /** 71 * @const addBtn タスクを追加するボタンを定義 72 * @const input タスク名を決める入力フィールドを定義 73 * @const addTaskTarget タスクを追加する場所を定義 74 */ 75 76 const addBtn = document.getElementById("addBtn"); 77 const input = document.getElementById("input"); 78 const addTaskTarget = document.getElementById("addTaskTarget"); 79 80 /** 81 * 関数名 addElements 82 * タスクに関連する要素群を追加する関数 83 * @param num 現在いくつタスクがあるかを示す引数 84 * @const elements Targetに挿入する要素群を定義した文字列 85 */ 86 87 const addElements = (num) => { 88 if (input.value) { 89 const elements = '<tr><td class="tdNum">' + num + "</td><td>" + input.value + '</td><td class="btn">作業中</td><td class="btn remove">削除</td></tr>'; 90 addTaskTarget.insertAdjacentHTML("beforeend", elements); 91 } 92 } 93 94 /** 95 * 関数名 removeElements 96 * タスクに関連する要素群を削除する関数 97 * @const removeBtn 各削除ボタンを定義 98 * @const numOfTask 現在挿入されているタスクの個数 99 */ 100 101 const removeElements = () => { 102 const removeBtn = document.getElementsByClassName("remove"); 103 const numOfTask = addTaskTarget.childElementCount; 104 for (let i = 0, maxLen = numOfTask; i < maxLen; i++) { 105 removeBtn[i].addEventListener("click", function () { 106 this.parentNode.remove(); 107 numChange(); 108 }); 109 } 110 } 111 112 /** 113 * 関数名 numChange 114 * 要素が消えたら各タスクIDの数字を変更する関数 115 * @const tdNum 各タスクIDが入っている要素群を定義 116 */ 117 118 const numChange = () => { 119 const tdNum = document.getElementsByClassName("tdNum"); 120 for (let i = 0, maxLen = tdNum.length; i < maxLen; i++) { 121 tdNum[i].textContent = ''; 122 } 123 for (let i = 0, maxLen = tdNum.length; i < maxLen; i++) { 124 tdNum[i].textContent = i; 125 } 126 } 127 128 /** 129 * 関数名 toggleTask 130 * タスクの追加、削除を出来るようにする関数 131 * @const numOfTask タスク追加Targetの子要素の数 132 */ 133 134 const toggleTask = () => { 135 addBtn.addEventListener("click", () => { 136 const numOfTask = addTaskTarget.childElementCount; 137 addElements(numOfTask); 138 removeElements(); 139 }); 140 } 141 142 toggleTask(); 143 144 </script> 145</body> 146 147</html>

投稿2020/07/20 17:39

Jon_do

総合スコア1373

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Jon_do

2020/07/20 18:02

~追記~ 何も書き込んでない場合はタスクを追加しないようにしています。
penny271

2020/07/21 11:17

確かに動きました! このようにコーディングすることで実装できるんですね! ありがとうございましたm(_ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問