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

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

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

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

Q&A

解決済

1回答

1166閲覧

DOMに追加した要素に対してクリックイベントを発火させたい

keisei-001

総合スコア15

JavaScript

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

0グッド

1クリップ

投稿2020/02/25 00:46

編集2020/02/25 01:56

前提・実現したいこと

JavaScriptで現在todoアプリを作成しています。
追加したtodoの詳細はlocalStorageを使って保存させています。

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

todoの一つずつにtodoの完了か未完了を表すボタンがあるのですがtodoを追加した要素に対してクリックイベントで要素の状態を変更するようにしたいのですが、追加後にはまだstatesという変数に要素が入っていないためstateChangeのクリックイベントに反応がしない。

該当のソースコード

javascript

1 2const tabChange = (tabs) => { 3 tabs.forEach((tab, index) => { 4 tab.addEventListener("click", (e) => { 5 tabs.forEach((tab) => tab.classList.remove("active")); 6 tab.classList.add("active"); 7 }) 8 }); 9} 10 11const Html = (id, content, state) =>{ 12 return `<tr class="detail"> 13 <td class="id">${id}</td> 14 <td class="content">${content}</td> 15 <td class="state"><input type="button" value="${state}"></td> 16 <td class="remove"><input type="button" value="remove"></td> 17 </tr>` 18} 19 20const stateChange = (states, todos) => { 21 states.forEach((state, index) => { 22 state.addEventListener("click", (e) => { 23 console.log(e) 24 const states = document.querySelectorAll(".main table .detail .state") 25 if (todos[index].state === "completed"){ 26 todos[index].state = "working"; 27 state.value = "working"; 28 } else if (todos[index].state === "working") { 29 todos[index].state = "completed"; 30 state.value = "completed"; 31 } 32 localStorage.setItem("todos", JSON.stringify(todos)) 33 }) 34 }); 35} 36 37const todoLists = (todos, tbody) => { 38 todos.forEach((todo) => { 39 tbody.insertAdjacentHTML('beforeend', Html(todo.id, todo.content, todo.state)) 40 }) 41} 42 43const todoAdd = (todos, tbody, states) =>{ 44 const input = document.querySelector('.main form .inputs input[type="text"]'); 45 const button = document.querySelector('.main form .inputs input[type="button"]'); 46 button.addEventListener("click", () => { 47 obj = { 48 id: todos.length + 1, 49 content: input.value, 50 state: "working" 51 } 52 input.value = ""; 53 todos.push(obj); 54 localStorage.setItem("todos", JSON.stringify(todos)); 55 tbody.insertAdjacentHTML('beforeend', Html(obj.id, obj.content, obj.state)) 56 location.reload(); 57 }); 58} 59const tabs = document.querySelectorAll(".main form .tabs label"); 60const todos = JSON.parse(localStorage.getItem("todos") || '[]'); 61const tbody = document.querySelector("table tbody") 62todoLists(todos, tbody);/*todoの一覧表示 */ 63tabChange(tabs);/*タブ切り替えイベント */ 64const states = document.querySelectorAll(".main table .detail .state input") 65// console.log(states) 66todoAdd(todos, tbody, states)/*todoの追加イベント */ 67stateChange(states, todos) 68 69

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <link rel="stylesheet" href="/ress.css"> 8 <link rel="stylesheet" href="/style.css"> 9 <title>ピュアJSでtodoアプリを作ってみた</title> 10</head> 11<body> 12 <section class="main"> 13 <h1>My-Todos</h1> 14 <form action="#" name="form"> 15 <div class="tabs"> 16 <label class="all">all<input type="radio" name="state" checked="checked"></label> 17 <label class="working">working<input type="radio"name="state"></label> 18 <label class="compuleted">completed<input class="state" type="radio"name="state"></label> 19 </div> 20 <div class="inputs"><input type="text"><input type="button" value="ADD"></div> 21 </form> 22 <table> 23 <tbody> 24 <tr class="head"> 25 <th>ID</th> 26 <th>CONTENT</th> 27 <th>STATE</th> 28 <th>REMOVE</th> 29 </tr> 30 <!-- ここに要素を追加します! --> 31 </tbody> 32 </table> 33 </section> 34 <script src="/script.js" defer></script> 35</body> 36</html>

試したこと

1.location.reload()を使ってtodoを追加後にリロードをさせて再度変数の読み込みをさせたがタブ切り替えをactiveというクラスの付け替えで対応したいるためactiveが消えてタブが初期表示に戻る。

2.変数のstates自体がNodeListという配列のような構造をしていたためここのpushで追加した要素を習得出来ないかやってみたがエラーになった。そもそもどのように追加要素を指定したらいいか不明。
お手数をおかけしますがよろしくお願いいたします。

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

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

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

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

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

miyabi_takatsuk

2020/02/25 00:56

HTMLの初期状態でも構いませんので、提示をお願いします。
keisei-001

2020/02/25 01:57

失礼いたしました。こちらHTMLを追記しております。よろしくお願いいたします。
guest

回答1

0

ベストアンサー

該当するdomの親(もしくはトップレベル)のdomに関数を設定して
セレクターと合致するかでコールバックを実行すればいいです

投稿2020/02/25 00:57

編集2020/02/25 01:13
yambejp

総合スコア114921

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

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

yambejp

2020/02/25 01:14

codepenにsampleあげました domで追加したd1/d2に対して d1は反応しませんが、d2は反応するのが確認できると思います
keisei-001

2020/02/25 03:00

ありがとうございます!Array.fomのメソッドも初めて見ましたがこのような使い方ができるのですね。とても勉強になりました。 ありがとうございました!
keisei-001

2020/02/25 03:01

コメント不足でしたがサンプルコードを参考にして対応が出来ました!ベストアンサーとさせていただきました。今後も何かありましたらよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問