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

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

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

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

996閲覧

javascriptでフィルター機能を作りたいのだが下記のエラー文が出て先に進めません。

cafe1111

総合スコア62

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2020/11/08 04:28

■問題点

javascriptでフィルター機能を作りたいのだが下記のエラー文が出て先に進めません。

Uncaught TypeError: Cannot set property 'display' of undefined
at NodeList.forEach (<anonymous>)
at HTMLSelectElement.filterTodo

js

1const todoList = document.querySelector(".todo-list"); 2const filterOption = document.querySelector('.filter-todo'); 3 4filterOption.addEventListener('click',filterTodo); 5 6function filterTodo(e){ 7 const todos = todoList.childNodes; 8 todos.forEach(function(todo){ 9 switch (e.target.value){ 10 case "all": 11 todo.style.display = "flex"; 12 break; 13 case "completed": 14 if(todo.classList.contains('completed')){ 15 todo.style.display = "flex"; 16 }else{ 17 todo.style.display = "none"; 18 } 19 } 20 }); 21}

todo.style.display = "flex";
これがエラーみたいなのですが記述はあっていると思うので何が行けないのかわからないです、、

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

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

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

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

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

guest

回答1

0

ベストアンサー

todo.style.display = "flex";

これがエラーみたいなのですが記述はあっていると思うので何が行けないのかわからないです、、

このエラーは頻出です。
どういうパターンで出てきて、どうすれば良いかを判断できないと辛いと思うので、
まずはそこを解説します。

Uncaught TypeError: Cannot set property 'display' of undefined at NodeList.forEach (<anonymous>) at HTMLSelectElement.filterTodo

Cannot set property 'display' of undefinedの部分に注目してください。
JSはオブジェクト指向言語なので、
値.プロパティ名という形式でプロパティを所持することが可能です。

しかしプロパティの所持が許されない例外中の例外が2つ存在します。

  • undefined
  • null

これらに対してプロパティのアクセスを試みた瞬間にエラーで死にます。
デベロッパーツールにこのようなコードを記述して……と、
同じエラーが出ましたね。

js

1> (undefined).hogehoge 2Uncaught TypeError: Cannot read property 'hogehoge' of undefined 3 at <anonymous>:1:13

更に深堀りしていきます。
今回の質問ではtodo.style.displayという指定をされましたが、
こういう流れになっています。

  • todo: 何かしらは存在している
  • todo.style: プロパティが存在しないのでundefined
  • todo.tyle.display: undefinedからプロパティを参照しようとしたのでエラー

じゃぁこのtodoって何者なのか?という話になります。

質問文のコードからMDNサイトで追っていくとこうなるのかな?
todoList.childNodes.forEach
このcurrentValue.styleが無いよって言ってるわけですね。

MDNサイトのExampleの結果を見るとこんなことが書いてありますね。

[object HTMLParagraphElement], 0, myThisArg [object Text], 1, myThisArg [object HTMLSpanElement], 2, myThisArg

あー、forEachで一覧取り出すと
テキストノードも対象になるんですね。

多分todoがテキストノードなので、
当然styleプロパティを所持しておらずエラーになる。

基本的にchildNodesなんかの低レイヤーの機能を使うとテキストノードのゴミが混ざります。
それでは機能実装が辛いと思いますので、
element.querySelectorAllを使ってtodo-listから絞り込み検索を使ってみてはどうでしょうか?

ただし、querySelectorAllは子要素ではなく子孫要素からの絞り込み検索になるので、
クラス名なんかを割り振ってあげて、子要素だけ取れるように調整してみてください。
改善例としてはこんなかんじ。

js

1const todoList = document.querySelector(".todo-list"); 2const filterOption = document.querySelector('.filter-todo'); 3 4filterOption.addEventListener('click',filterTodo); 5 6function filterTodo(e){ 7 const todos = todoList.querySelectorAll(".todo"); 8 todos.forEach(function(todo){ 9 switch (e.target.value){ 10 case "all": 11 todo.style.display = "flex"; 12 break; 13 case "completed": 14 if(todo.classList.contains('completed')){ 15 todo.style.display = "flex"; 16 }else{ 17 todo.style.display = "none"; 18 } 19 } 20 }); 21}

投稿2020/11/08 05:12

編集2020/11/09 03:50
miyabi-sun

総合スコア21158

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

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

cafe1111

2020/11/08 05:46

なるほど! すごくわかりすく説明していただきありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問