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

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

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

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

Q&A

解決済

1回答

5224閲覧

appendChildをした時のエラーを解決したい。

F_Yohei

総合スコア14

JavaScript

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

0グッド

0クリップ

投稿2020/12/01 04:30

前提・実現したいこと

作業状態を管理するbuttonタグを作成する関数を作り、動的に生成したtrタグに追加したい。

該当のソースコード

HTML

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Document</title> 8</head> 9 10<body> 11 <h1>ToDoリスト</h1> 12 <form> 13 <input type="radio" name="state">すべて 14 <input type="radio" name="state">作業中 15 <input type="radio" name="state">完了 16 </form> 17 18 <div> 19 <table> 20 <thead> 21 <tr> 22 <th>ID</th> 23 <th>コメント</th> 24 <th>状態</th> 25 </tr> 26 </thead> 27 <tbody id="todoList"> 28 29 </tbody> 30 </table> 31 32 </div> 33 34 <h2>新規タスクの追加</h2> 35 <form> 36 <input type="text" id="todoInput" value=""> 37 <button type="submit" value="追加" id="addTaskButton">追加</button> 38 </form> 39 <script src="main.js"></script> 40</body> 41 42</html>

JavaScript

1const todoList = document.getElementById('todoList'); 2const addTaskButton = document.getElementById('addTaskButton'); 3const textBox = document.getElementById('todoInput'); 4 5const todos = []; 6 7addTaskButton.addEventListener('click', (e) => { 8 e.preventDefault(); 9 const todoInput = { task: textBox.value, state: '作業中' }; 10 textBox.value = ''; 11 if (todoInput.task.match(/\S/g)) { 12 //空白以外の文字に一致したら配列に追加 13 todos.push(todoInput); 14 textBox.focus(); 15 } 16 addTask(); 17}); 18 19//配列に格納されたToDoをHTMLに表示させる為の関数 20const addTask = () => { 21 while (todoList.firstChild) { 22 todoList.removeChild(todoList.firstChild); 23 } 24 25 todos.forEach((todo, id) => { 26 const tr = document.createElement('tr'); 27 todoList.appendChild(tr); 28 29 const idTd = document.createElement('td'); 30 const comment = document.createElement('td'); 31 const stateTd = document.createElement('td'); 32 const deleteTd = document.createElement('td'); 33 34 tr.appendChild(idTd); 35 tr.appendChild(comment); 36 tr.appendChild(stateTd); 37 tr.appendChild(deleteTd); 38 39 idTd.innerHTML = id; 40 comment.innerHTML = todo.task; 41 42 stateTd.appendChild(createStateButton()); 43 44 }); 45}; 46 47//状態を管理する為のボタンを作成する関数 48const createStateButton = () => { 49 const workingBtn = document.createElement('button'); 50 workingBtn.innerHTML = '作業中'; 51}; 52 53//ToDoを削除するボタンを作る為の関数 54const createDeleteButton = () => { 55 const deleteBtn = document.createElement('button'); 56 deleteBtn.innerHTML = '削除'; 57};

 

###エラー内容

Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
at main.js:42
at Array.forEach (<anonymous>)
at addTask (main.js:25)
at HTMLButtonElement.<anonymous> (main.js:16)

###試したこと

JavaScript

1const todoList = document.getElementById("todoList"); 2const addTaskButton = document.getElementById("addTaskButton"); 3const textBox = document.getElementById("todoInput"); 4 5const todos = []; 6 7addTaskButton.addEventListener("click", (e) => { 8 e.preventDefault(); 9 const todoInput = { task: textBox.value, state: "作業中" }; 10 textBox.value = ""; 11 if (todoInput.task.match(/\S/g)) { 12 //空白以外の文字に一致したら配列に追加 13 todos.push(todoInput); 14 textBox.focus(); 15 } 16 addTask(); 17}); 18 19//配列に格納されたToDoをHTMLに表示させる為の関数 20const addTask = () => { 21 while (todoList.firstChild) { 22 todoList.removeChild(todoList.firstChild); 23 } 24 25 todos.forEach((todo, id) => { 26 const tr = document.createElement("tr"); 27 todoList.appendChild(tr); 28 29 const idTd = document.createElement("td"); 30 const comment = document.createElement("td"); 31 const stateTd = document.createElement("td"); 32 const deleteTd = document.createElement("td"); 33 34 tr.appendChild(idTd); 35 tr.appendChild(comment); 36 tr.appendChild(stateTd); 37 tr.appendChild(deleteTd); 38 39 idTd.innerHTML = id; 40 comment.innerHTML = todo.task; 41 42 createStateButton(stateTd); 43 createDeleteButton(deleteTd); 44 }); 45}; 46 47//状態を管理する為のボタンを作成する関数 48const createStateButton = (stateTd) => { 49 const workingBtn = document.createElement("button"); 50 workingBtn.innerHTML = "作業中"; 51 stateTd.appendChild(workingBtn); 52}; 53 54//ToDoを削除するボタンを作る為の関数 55const createDeleteButton = (deleteTd) => { 56 const deleteBtn = document.createElement("button"); 57 deleteBtn.innerHTML = "削除"; 58 deleteTd.appendChild(deleteBtn); 59};

このようにボタンを作成する関数を呼び出す際に引数を渡し、関数の中でappendChildするとエラーもなく表示されましたが、実現したいのはボタンを生成する処理とボタンをHTMLに表示させる処理をを分けたいということです。

ご教授いただけると幸いです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

createStateButtonがreturn workingBtn されていません

投稿2020/12/01 04:44

yambejp

総合スコア114775

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

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

F_Yohei

2020/12/01 05:48

ありがとうございます! 解決しました! 何故そのような挙動になるのかを教えていただきたいです。 今回のエラー内容はappendChildをする時はそれがノードじゃないとできないという意味だと思うのですが、returnせずにappendChild内で関数だけ呼び出すとそれがノードだと認識されずにエラーが起きてしまいcreateElementで生成したworkingBtnをreturnすることによって、ノードだと認識され親要素に追加されるという認識でいいでしょうか? 重ねての質問恐れ入りますが、ご教授いただければ幸いです????‍♂️
yambejp

2020/12/02 06:19

createStateButtonがHTML要素を返さないとせっかく作ったworkingBtnが 破棄されて、戻り値はundefinedです。 undefinedをstateTdにappendChildしようとしてもエラーになるという流れです
F_Yohei

2020/12/03 00:02

そうなんですね!! 丁寧に教えてくださりありがとうございます☺️
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問