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

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

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

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

Q&A

解決済

4回答

4856閲覧

Javascript 追加したボタンで要素を削除する方法

mikeikeikename

総合スコア15

JavaScript

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

0グッド

0クリップ

投稿2020/06/18 11:53

編集2020/06/18 11:57

前提・実現したいこと

JavascriptのDOM操作で、追加したボタン要素(削除ボタン)を使って
追加したtd要素を削除したいと考えておりますが、以下のエラーコードが出てしまいます。

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

Uncaught TypeError: Failed to execute 'addEventListener' on 'EventTarget': 2 arguments required, but only 1 present. at HTMLButtonElement.<anonymous> (main.js:57)

HTML

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel ="stylesheet" href="css/style.css"> <title>Todoリスト</title> </head> <body> <h1>Todoリスト</h1> <p> <input type="radio" name="status" value="1" checked="checked">全て <input type="radio" name="status" value="2">作業中 <input type="radio" name="status" value="3">完了 </p> <p></p> <table> <thead> <th>ID</th> <th>コメント</th> <th>状態</th> <th></th> </thead> <tbody class ="addTask-target"></tbody> </table> <h2>新規タスクの追加</h2> <input class="addTask-value" type="text" /> <button class="addTask-trigger" type="button">追加</button> <script src="js/main.js"></script> </body> </script> </html>

###Javascript

document.addEventListener('DOMContentLoaded', function() { const addTaskTrigger = document.getElementsByClassName('addTask-trigger')[0]; const addTaskTarget = document.getElementsByClassName('addTask-target')[0]; const addTaskValue = document.getElementsByClassName('addTask-value')[0]; let nextId = 0; const todos = []; const addTask = (task,id) => { //テーブル要素を生成する td要素を作る const tableItem = document.createElement('tr'); const addButtonTd = document.createElement('td'); const idSpanTd = document.createElement('td'); const taskSpanTd = document.createElement('td'); const removeButtonTd = document.createElement('td'); //Button要素を生成する const addButton = document.createElement('button') const removeButton = document.createElement('button') //要素内のHTML文章を変更する addButton.innerText = '作業中'; removeButton.innerText = '削除'; idSpanTd.innerText = id; taskSpanTd.innerText = task; //生成したテーブル要素をブラウザに表示する tableItem.append(idSpanTd); tableItem.append(taskSpanTd); tableItem.append(addButtonTd); tableItem.append(removeButtonTd); addTaskTarget.appendChild(tableItem); //生成したbutton要素を生成する addButtonTd.append(addButton); removeButtonTd.append(removeButton); const todo = { task: 'taskSpanTd', status: '作業中' }; todos.push(todo); }; function delete_element(){ tbody.remoChild(tbody.firstChild); } addTaskTrigger.addEventListener('click',() => { const task = addTaskValue.value; addTask(task,nextId ++); addTaskValue.value = ''; const delete_value =document.querySelector('button'); delete_value.addEventListener('click, delete_element, false') }); });

試したこと

function delete_element(){ tbody.remoChild(tbody.firstChild); } addTaskTrigger.addEventListener('click',() => { const task = addTaskValue.value; addTask(task,nextId ++); addTaskValue.value = '';

上記、削除と追加を同じ関数でまとめましたが、上手く動作せずでした。
delete_elementが認識されていないのでその辺りに問題があるのかなと考えています。

ID、classなどを取得して、加工して、HTMLに戻すという一連の動作は頭で理解しているのですが、
HTMLには削除ボタンに関するID、classがついていないため、こういった場合はどうするのかわからない状況です。
(削除ボタンがremoveButtonTd.append(removeButton);とJavascriptで生成された要素であるため)

お手数ですがご確認、ご教示宜しくお願い致します。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答4

0

ベストアンサー

検証はしておりませんが、取り急ぎ後ろから3行目の delete_value.addEventListener('click, delete_element, false') はエラーになりますよね。
全部文字列で囲ってしまっています。


とりあえず動くまで持っていきました。
delete_elementaddTaskTarget に付与し、delete_element 内でボタンが押されたかどうか判断するようにしました。

javascript

1document.addEventListener('DOMContentLoaded', function() { 2 const addTaskTrigger = document.getElementsByClassName('addTask-trigger')[0]; 3 const addTaskTarget = document.getElementsByClassName('addTask-target')[0]; 4 const addTaskValue = document.getElementsByClassName('addTask-value')[0]; 5 let nextId = 0; 6 const todos = []; 7 8 const addTask = (task, id) => { 9 //テーブル要素を生成する td要素を作る 10 const tableItem = document.createElement('tr'); 11 const addButtonTd = document.createElement('td'); 12 const idSpanTd = document.createElement('td'); 13 const taskSpanTd = document.createElement('td'); 14 const removeButtonTd = document.createElement('td'); 15 16 //Button要素を生成する 17 const addButton = document.createElement('button') 18 const removeButton = document.createElement('button') 19 20 //要素内のHTML文章を変更する 21 addButton.innerText = '作業中'; 22 removeButton.innerText = '削除'; 23 idSpanTd.innerText = id; 24 taskSpanTd.innerText = task; 25 26 //生成したテーブル要素をブラウザに表示する 27 tableItem.append(idSpanTd); 28 tableItem.append(taskSpanTd); 29 tableItem.append(addButtonTd); 30 tableItem.append(removeButtonTd); 31 addTaskTarget.appendChild(tableItem); 32 33 //生成したbutton要素を生成する 34 addButtonTd.append(addButton); 35 removeButtonTd.append(removeButton); 36 37 const todo = { 38 task: 'taskSpanTd', 39 status: '作業中' 40 }; 41 todos.push(todo); 42 }; 43 44 function delete_element(ev) { 45 if (ev.target instanceof HTMLButtonElement && ev.target.textContent === '削除') { 46 const row = ev.target.closest('tr'); 47 addTaskTarget.removeChild(row); 48 } 49 } 50 51 addTaskTrigger.addEventListener('click', () => { 52 const task = addTaskValue.value; 53 addTask(task, nextId++); 54 addTaskValue.value = ''; 55 }); 56 addTaskTarget.addEventListener('click', delete_element, false); 57});

投稿2020/06/18 12:10

編集2020/06/18 12:35
htsign

総合スコア870

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

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

mikeikeikename

2020/06/18 12:12

ご確認ありがとうございます。 失礼しました、ご指摘のところ、確かにそうですね。エラーはこちらで消えましたが、反応はしないようです。。
htsign

2020/06/18 12:20

あとは、そうですね。 document.querySelector('button') は「ドキュメントから最初に見つかる button」を意味するので違う要素にイベントリスナが紐付いてしまっていますね。 それから remoChild と typo してしまっている行があります。 removeChild に直しましょう。 一度こちらでも動くもの書いてみたいと思います。
htsign

2020/06/18 12:36

たぶん通知が飛んでるかと思いますが、一応動くものを追記しておきました。
mikeikeikename

2020/06/18 14:22

htsign様 ありがとうございます。無事動かすことが出来ました。 ちなみに、削除した後に一番左手のインデックスを初期化(0からに戻す)する場合は、trごと削除するような実装になりますでしょうか。
htsign

2020/06/18 14:30 編集

インデックスを初期化するには addTask の第二引数に渡す数字が 0 になればよいので、 nextId に 0 を代入すればよいと思います。 ただし、他に残っているtodoタスクがあるのにも関わらず 0 に戻してしまうとそれはそれで変なので、 todos が空になったかどうかのチェックは必要かと思います。 もしくは「いつどのtodoタスクを削除しても上から順に必ず 0, 1, 2, ... と並んでほしい」ということでしたら、削除後に残ったそれぞれの td の innerText に対して 0 から振り直す処理が必要です。 これをするのであれば addTask に id を渡す処理自体が不要になり、必然的に nextId もコードから消してよいことになりますね。 trごと削除してあげないと、いろいろと面倒な処理が増えることになりそうです。
mikeikeikename

2020/06/18 14:30

承知致しました。 ありがとうございます。 やってみます。
guest

0

中略

js

1 //生成したbutton要素を生成する 2 addButtonTd.append(addButton); 3 removeButtonTd.append(removeButton); 4 5 const todo = { 6 task: 'taskSpanTd', 7 status: '作業中' 8 }; 9 todos.push(todo); 10 11 removeButton.addEventListener('click', delete_element, false); 12 13 }; 14 15 function delete_element () { 16 let tr = this.closest ('tr'); 17 if (tr) 18 tr.remove (); 19 } 20

そもそも

js

1delete_value.addEventListener('click, delete_element, false')

は構文エラー!

個人的には無駄が多すぎます。

投稿2020/06/18 12:15

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

mikeikeikename

2020/06/18 14:24

one_line様 初歩的な部分のご教示ありがとうございます。 まだまだ無駄が多いので修正していきます。
guest

0

全部文字列になっているので、下記のように修正してみてください。

js

1// delete_value.addEventListener('click, delete_element, false') 2// ↓ ↓ 3 delete_value.addEventListener('click', delete_element, false)

ただ、複数増えていく削除ボタンがすべて同じ位置の要素(最初の要素)を削除することになるので、それが正しい実装かは考えてみてください。

また、document.querySelector('button')で取得できるのはHTML中の全てのボタンの中で最初に現れたボタンなので、同じボタンに削除イベントをいくつも付与することになることも注意したほうが良いです。

投稿2020/06/18 12:14

kei344

総合スコア69407

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

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

mikeikeikename

2020/06/18 14:23

kei344様 いつもありがとうございます。 上記諸々承知致しました。selectorよりもIdで取得した方が賢明ですね。
kei344

2020/06/18 14:26

Idで取得よりもエレメント作ったところでイベントをつけるほうが良いです。(削除も簡単だし)
mikeikeikename

2020/06/18 14:29

承知致しました。 ありがとうございます。勉強になりましたm(_ _)m
guest

0

javascript

1<script> 2window.addEventListener('DOMContentLoaded',()=>{ 3 let id=0; 4 document.querySelector('.addTask-trigger').addEventListener('click',()=>{ 5 const tr=[ 6 document.createTextNode(id++), 7 document.createTextNode(document.querySelector('.addTask-value').value), 8 Object.assign(document.createElement('button'),{textContent:"削除",className:'del'}), 9 Object.assign(document.createElement('button'),{textContent:"作業中"}), 10 ].map(x=>[x].reduce((x,y)=>(x.appendChild(y),x),document.createElement('td'))) 11 .reduce((x,y)=>(x.appendChild(y),x),document.createElement('tr')); 12 document.querySelector('.addTask-target').appendChild(tr); 13 }); 14 document.querySelector('.addTask-target').addEventListener('click',(e)=>{ 15 if(e.target.classList.contains('del')){ 16 const tr=e.target.closest('tr'); 17 tr.parentNode.removeChild(tr); 18 } 19 }); 20}); 21</script> 22<table> 23<thead> 24<th>ID</th> 25<th>コメント</th> 26<th>状態</th> 27<th></th> 28</thead> 29<tbody class ="addTask-target"></tbody> 30</table> 31<h2>新規タスクの追加</h2> 32<input class="addTask-value" type="text" /> 33<button class="addTask-trigger" type="button">追加</button>

投稿2020/06/18 14:45

yambejp

総合スコア114839

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問