🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

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

リファクタリング

リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

Q&A

解決済

2回答

9217閲覧

【JavaScript:エラー対処法】Uncaught TypeError: Cannot read property '' of undefined

oyatk

総合スコア8

JavaScript

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

リファクタリング

リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

0グッド

0クリップ

投稿2021/03/14 13:17

前提・実現したいこと

JavaScript初心者です。
JavaScriptの実装演習として4択クイズアプリケーションを制作中です。
ボタンを押すと正誤判定のロジックが回り、正解か不正解か表示するロジックを組んでいます。

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

もし、4択のボタンのうちテキスト内容(textContent)が同じならば正解、それ以外なら不正解というロジックを各ボタン(4個)それぞれにコーディングしたのですが同じような命令が4つ並んでいたのでwhile文で一つにまとめよう(リファクタリングしよう)と思いコードを修正していたところ以下のエラーが発生してしまいました。

Uncaught TypeError: Cannot read property 'textContent' of undefined at HTMLDivElement.<anonymous> (quiz.js:99)

while文に直す前は正常に動いていたのですが、wihleの中に入れたらエラーになってしまいました。

該当のソースコード

JavaScript

1 const $answer_block_js = document.getElementsByClassName("answer-block"); 2 const $answer_text_js = document.getElementsByClassName("answer-text"); 3 let click_counter = 0; 4/*リファクタリング前(問題なく動いていた) 5 $answer_block_js[0].addEventListener("click",() => { 6 if(quiz_contents[0].correct === $answer_text_js[0].textContent) 7 { 8 window.alert("正解!"); 9 } 10 else 11 { 12 window.alert("不正解!"); 13 } 14 }); 15 16 $answer_block_js[1].addEventListener("click",() => { 17 if(quiz_contents[0].correct === $answer_text_js[1].textContent) 18 { 19 window.alert("正解!"); 20 } 21 else 22 { 23 window.alert("不正解!"); 24 } 25 }); 26 27 $answer_block_js[2].addEventListener("click",() => { 28 if(quiz_contents[0].correct === $answer_text_js[2].textContent) 29 { 30 window.alert("正解!"); 31 } 32 else 33 { 34 window.alert("不正解!"); 35 } 36 }); 37 38 $answer_block_js[3].addEventListener("click",() => { 39 if(quiz_contents[0].correct === $answer_text_js[3].textContent) 40 { 41 window.alert("正解!"); 42 } 43 else 44 { 45 window.alert("不正解!"); 46 } 47 }); 48 49 */ 50 //リファクタリング後(ifの条件でエラー) 51 while(click_counter<$answer_block_js.length) 52 { 53 $answer_block_js[click_counter].addEventListener("click",() => { 54 if(quiz_contents[0].correct === $answer_text_js[click_counter].textContent) 55 { 56 window.alert("正解!"); 57 } 58 else 59 { 60 window.alert("不正解!"); 61 } 62 }); 63 64 console.log($answer_block_js[click_counter]); 65 console.log($answer_text_js[click_counter].textContent); 66 67 click_counter++; 68 } 69 70 console.log(quiz_contents[0].correct); 71

HTML

1 <div class="answer-block px-3 py-2 m-2"> 2 <p class="answer-text"></p> 3 </div> 4 <div class="answer-block px-3 py-2 m-2"> 5 <p class="answer-text"></p> 6 </div> 7 <div class="answer-block px-3 py-2 m-2"> 8 <p class="answer-text"></p> 9 </div> 10 <div class="answer-block px-3 py-2 m-2"> 11 <p class="answer-text"></p> 12 </div>

試したこと

Uncaught TypeError: Cannot read property 'textContent' of undefinedであったので、textContentを取得するものがないのかと思い、

JavaScript

1console.log($answer_block_js[click_counter]); 2console.log($answer_text_js[click_counter].textContent);

を試したのですがどちらも正常に取得出来ました。
どこを修正すればよいのかエラーが直るのか詰まってしまいました。。。

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

どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

js

1while (click_counter < $answer_block_js.length) { 2 let cnt = click_counter; 3 $answer_block_js[click_counter].addEventListener("click", () => { 4 // click_counter の値が $answer_block_js.length と同じになっているはず。 5 console.log(click_counter); 6 console.log(cnt); // これで思っている値は採れませんか? 7 }); 8 click_counter++; 9}

投稿2021/03/16 09:49

kei344

総合スコア69596

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

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

oyatk

2021/03/16 10:08

ご回答ありがとうございます。 解決いたしました! ご教授誠にありがとうございます。 原因の質問なのですが、一つのWhileの中で変数の使いまわしは良くなかったということでしょうか。
kei344

2021/03/16 13:38

使い回しというより変数のスコープの問題です。変数がいつどのタイミングで更新されるかを注意してみてください。( y_waiwai さんが「そのエラーが出たところの変数の値がどうなってるか見てみればどうでしょう」とおっしゃっている部分です)
oyatk

2021/03/16 15:22

原因は変数のスコープの旨、承知いたしました。 以後、注意しながら実装してみます。 ご対応、ありがとうございました!
guest

0

Uncaught TypeError: Cannot read property 'textContent' of undefined

undefined の変数には 'textContent'というプロパティがありません、とおっしゃってますよ。
そのエラーが出たところの変数の値がどうなってるか見てみればどうでしょう

投稿2021/03/14 14:05

y_waiwai

総合スコア88038

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

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

oyatk

2021/03/14 14:27

ご回答誠にありがとうございます。 該当の変数($answer_text_js[click_counter])をconsole.logで確認したところ、文字列が入っている<p>が正常に取得できました。また、$answer_text_js[click_counter].textContentもconsole.logで確認したところ意図した文字列を取得することが出来ました。 ただこれをIFの条件分岐に入れるとエラーが起きてしまします。原因をご教授いただけますと幸いです。 どうぞよろしくお願いいたします。
y_waiwai

2021/03/14 22:06

click_counterの値はどうなってますか。配列の範囲超えるとコケますよ
oyatk

2021/03/16 06:48

返信が遅れ申し訳ありません。 console.log(click_counter);を確認したところ、0,1,2,3と数字が取れました。($answer_text_jsのlengthは4です。) If文の条件分岐には特殊な書き方が必要などあるのでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問