undef datalistがundefinedに

このQ&Aのポイント
  • datalistがundefinedになることがあります。
  • datalistの要素が正しく設定されていない場合に、datalistがundefinedになります。
  • localStorageへのデータ保存時に、datalistが正しく保存されないことがあります。
回答を見る
  • ベストアンサー

undef datalistがundefinedに

javascript datalistがundef datalistがundefinedになります。 var datalist = { data3: "hoge3", } // str=[]; var a = { data1: "hoge1", data2: "hoge2" } function SaveDataToLocalStorage(datalist) { var a = []; a.push(JSON.parse(localStorage.getItem('session'))); localStorage.setItem('session', JSON.stringify(a)); // Parse the serialized data back into an aray of objects a = JSON.parse(localStorage.getItem('session')) || []; // Push the new data (whether it be an object or anything else) onto the array alert(datalist); a.push(datalist); console.log(datalist); // Alert the array value alert(a+"datalist"); // Should be something like [Object array] // Re-serialize the array back into a string and store it in localStorage localStorage.setItem('session', JSON.stringify(a)); }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.23

>このサイトは回答者さんからの投稿がないと >補足投稿が1回しか投稿できない仕組みになっているみたいです。 あれ^^知らなかった^^ んま~こちら、PHPももちろん使えますが^^ 掲示板としては、あ~なるほど~の空気の方がおいしいかな~ なんというか・・・ 1~10まで全部作って動いたとして 「理解もせずただ使って終わり?」なら、 面白さを感じないので^^そこらへんがね~ってのは ありますね。 それと、このサイト「長いソース書けない」ってのは 結構致命的かもですね~。 ともあれ、この板結構楽しめたのでありがとね~ 一回終わりましょか! なお、こちらプログラマーじゃなかったりしますけどね。 水商売で、暇つぶしにプログラムしてるだけなので。

panja2021
質問者

お礼

こちらは行政書士の勉強をしながらカバンを作っています。ただのカバン職人です。 元、プログラマーです。 クイズ問題の作成お手数代していただいてすごく助かりました。 新たにスレッドを立て直しました、お暇なときでいいのでよろしくお願いします。 https://okwave.jp/qa/q10001082.html

その他の回答 (22)

回答No.22

あれ、質問者さんいなくなっちゃったか^^ また、気が向いたら!声かけてくださいな! ではでは!

panja2021
質問者

補足

返事が遅れてすみません。このサイトは回答者さんからの投稿がないと 補足投稿が1回しか投稿できない仕組みになっているみたいです。 いつも助かっています。 悩みが解決されました。ありがとうございます。 さすがです。気づきませんでした。 私よりすごいなぁと思いますた。 ちょうど、再テストの機能、ほしかった機能なんです! さすが。やっぱりAsarKingChangさんみたいに経験があると違いますね。 ありがとうございました。 次のネタに行きましょうか? EXCELネタを考えてみました。 次は、質問と選択肢、答えの番号をあらかじめEXCELに保存しておいてそれをデータベース接続して HTMLの画面に表示させる機能の追加です。 現在はソースコードに直接記述している部分をEXCELのワークシートからデータを取得してくる機能がほしいです。」 この方法だとプログラミングに詳しくない人でもソースコードを直接触らずにEXCELのワークシートを編集すれば済むと思います。 ここにPHPで作ったサンプルがあります。 EXCELのa列には英単語、b列には英単語の日本語の意味があらかじめ記述しているワークシートを作成してください。 たとえば --------------------- a列   |b列 abolish | 廃止する accord  | 一致 acid  | 酸っぱい assert  | 断言する blade | 刃物 --------------------- >これは英単語を1件表示するサンプルです。 <?php // Excelの初期処理 $file_name = dirname(__FILE__) . "\\word.xls"; $conn = new COM("ADODB.Connection") or die("エラー"); $rs = new COM("ADODB.Recordset") or die("エラー"); // データベースへの接続 $dsn = "Driver={Microsoft Excel Driver (*.xls)};DBQ=$file_name;"; $conn->Open($dsn); // 1件の表示 $sql = "SELECT * FROM [Sheet1$]"; $rs->Open($sql, $conn, 3, 3); echo $rs["q"]->Value; // データベースを閉じる $rs->Close(); $conn->Close(); ?> -------------------------------- >これは英単語クイズのサンプルです。 <?php // セッションの開始 session_start(); // クリックされたボタンの取得 if (isset($_POST["sub"])) { $sub = htmlspecialchars($_POST["sub"], ENT_QUOTES); } else { $sub = ""; } // 選択されたラジオボタンの取得 if (isset($_POST["sel"])) { $sel = intval($_POST["sel"]); } else { $sel = 9; } // Excelの初期処理 $file_name = dirname(__FILE__) . "\\word.xls"; $conn = new COM("ADODB.Connection") or die("エラー"); $rs = new COM("ADODB.Recordset") or die("エラー"); // データベースへの接続 $dsn = "Driver={Microsoft Excel Driver (*.xls)};DBQ=$file_name;"; $conn->Open($dsn); // 解答の照合 if ($sub == "解答") { if ($sel == $_SESSION["a_idx"]) { $str_a = "正解です<br />"; } else { $str_a = "間違いです!<br />"; } $str_a .= "{$_SESSION["q"]} → {$_SESSION["a"]}<hr>次の問題:"; } // 総問題数の取得 $sql = "SELECT COUNT(*) FROM [Sheet1$]"; $rs->Open($sql, $conn); $max = $rs[0]->Value; $rs->Close(); // 選択肢の作成 $ar = range(1, $max); shuffle($ar); $sql = "SELECT * FROM [Sheet1$]"; $rs->Open($sql, $conn, 3, 3); $questions = array(); for ($i = 0; $i < 3; $i++) { $rs->AbsolutePosition = $ar[$i]; $questions[$i]["q"] = to_sjis($rs["q"]->Value); $questions[$i]["a"] = to_sjis($rs["a"]->Value); } // 正解の選択肢番号を取得 $a_idx = rand(0, 2); // 正解をセッションに格納 $_SESSION["q"] = $questions[$a_idx]["q"]; $_SESSION["a"] = $questions[$a_idx]["a"]; $_SESSION["a_idx"] = $a_idx; // 表示用の問題と選択肢を作成 $str_q = "<b>{$questions[$a_idx]["q"]}</b><br />"; for ($i = 0; $i < 3; $i++) { $str_q .= "<input type=\"radio\" name=\"sel\" value=\"{$i}\">"; $str_q .= "{$questions[$i]["a"]}<br />"; } // データベースを閉じる $rs->Close(); $conn->Close(); // 文字コードの変換 function to_sjis($a) { return mb_convert_encoding($a, "EUC-JP", "SJIS"); } ?> <html> <head> <meta http-equiv="content-type" content="text/html; charset=euc-jp"> <title>英単語クイズ</title> </head> <body> <p>英単語クイズ</p> <form method="post" action="<?php echo $_SERVER["SCRIPT_NAME"]; ?>"> <?php echo $str_a; ?> <?php echo $str_q; ?> <p><input type="submit" name="sub" value="解答"></p> </form> </body> </html> ------------------------------- これをjavascriptに置き換えてください。 1.エクセルのシートに今、ソースコードに直接記述してある質問文、選択肢、答えの番号を記述したものを用意してください。 2.そのデータをデータベース接続してエクセルのワークシートから値を取得してHTMLに表示させてください。 これが実現できれば一般の人でもソースコードを直接触らずにクイズ問題プログラムを作成できるはずです。 わからない部分があればまた、回答に投稿してください、ただし補足投稿ができるのは1回しかできないサイトの作りになっていますので、また、回答に投稿し直してください。 気に入らなければ、次のネタの準備に入ります。サンプルソースを準備するのに少し時間が掛かりますが、お待ち下さい。 よろしくお願いします。

回答No.21

暇つぶしに書いてる関係で^^ if (typeof this.user_answer[this.mondai_no] === "undefined") { if (user_answer !== undefined) { 2種類の、undefined判定があったり(意味は同じ)してますが^^ さらっと、気にしないでね。。(なお、typeofにする方が理想) 質問者さんは、気が付いたと思いますが、これ。。 this.mondai_no=0; this.user_answer=[]; たったの2変数だけで動いてます。INT+INT[] ものすごくメモリも、エコなので、これ以上、、、 メモリを節約はほぼ^^無理でしょうね。 ってことで、先ほどのが動いたら、終わりますか~ (別に任せますけど) 今回、ソース内に自分自身をコールするプログラムが混ざっていますが、 これも、ポイントかな~。 プログラムって、サブルーチンでほとんど同じ処理なんだけどな~って 時はよく出るんですが、そういう時、「だったら自分自身を呼んじゃえば?」 って時、使う手です。

回答No.20

// コンストラクタ function QA(mondai_data) { this.mondai_data=mondai_data; this.mondai_no=0; this.user_answer=[]; this.next_mondai(); this.clear(); } //今選択されている問題が「回答済み」で「正解」なら1問次を参照する。 //ただし次の問題がない場合は、falseを返す。 QA.prototype.next_mondai = function() { if (this.mondai_no>=this.mondai_data.length) { return(false); } // 未回答 if (typeof this.user_answer[this.mondai_no] === "undefined") { return(true); } if (this.user_answer[this.mondai_no]==this.mondai_data[this.mondai_no].c) { // 正解 this.mondai_no++; return(this.next_mondai()); }else{ // 不正解 return(true); } } //回答判断 QA.prototype.answer = function(user_answer) { //この問題の選択肢の数は自動判断(選択肢は何個でもOKです) var answer_count=this.mondai_data[this.mondai_no].a.length; if (user_answer>=answer_count) { // 通常あり得ないが選択肢よりも大きい回答が来た場合エラーとする document.getElementById("text_s").innerHTML = "error"; return; } // ユーザーが答えた回答を覚えておく this.user_answer[this.mondai_no]=user_answer; if (user_answer==this.mondai_data[this.mondai_no].c) { document.getElementById("text_s").innerHTML = "正解"; }else{ document.getElementById("text_s").innerHTML = "不正解 答えは" + this.mondai_data[this.mondai_no].a[this.mondai_data[this.mondai_no].c] + "でした"; } this.mondai_no++; if (this.next_mondai()) { // 次の問題がまだある document.getElementById("text_n").innerHTML = "【<a href='javascript:test.next()'>次の問題へ</a>】"; }else{ // 次の問題はもうない→終了 document.getElementById("text_n").innerHTML = "【<a href='javascript:test.Kekka()'>結果発表</a>】"+ "【<a href='javascript:test.Csv()'>CSV出力</a>】"; } // このデータ類を保存したい場合→SaveDataToLocalStorage // 最後にまとめて保存なら、[終了]の部分にSaveDataToLocalStorageを入れればOK // 毎回保存したいなら、この位置にSaveDataToLocalStorageでもOKです。 console.log('[ユーザーの回答ログ]'); console.log(this.user_answer); } //初めから(回答は消さない) QA.prototype.restart_not_clear = function() { this.mondai_no=0; this.clear(); this.next_mondai(); this.quiz(); } //初めから QA.prototype.restart = function() { this.mondai_no=0; this.user_answer=[]; this.clear(); this.next_mondai(); this.quiz(); } // 結果発表 QA.prototype.Kekka = function() { var mondai_max=this.mondai_data.length; var inner=""; var wrong=0; // その他の表示物を消す this.clear(); inner="<table border='2'><caption>成績発表</caption><tr><th>問題</th><th>成績</th></tr>"; for (var mondai_index=0;mondai_index<mondai_max;mondai_index++) { inner+="<tr>"; inner+="<td>"+"問題"+(mondai_index+1)+"</td>"; var user_answer=this.user_answer[mondai_index]; if (user_answer !== undefined) { if (user_answer==this.mondai_data[mondai_index].c) { inner+="<td>正解</td>"; }else{ inner+="<td>不正解</td>"; wrong++; } }else{ inner+="<td>未回答</td>"; wrong++; } inner+="</tr>"; } inner+="</table>"; // 未回答または不正解が1問でもある時のみ if (wrong) { inner+="【<a href='javascript:test.restart_not_clear()'>同じ問題を最初から(間違えた問題のみ)</a>】"; } inner+="【<a href='javascript:test.restart()'>同じ問題を最初から</a>】"; document.getElementById("text_n").innerHTML = inner; } ---------------------------- 原理は、 this.user_answer=[]; ユーザーが回答したデータ配列が、 "undefined"なら、未回答→正解はしていないと判定 問題テーブルの、"c"と違うなら→不正解 それ以外は「次の問題」を選択 ただし、「最後の問題」より先を指す場合「クイズ終了」を フラグとして返却 それを、 this.mondai_no++; if (this.next_mondai()) { // 次の問題がまだある }else{ // 次の問題はもうない→終了 。。今まで通り、あるなしで分岐 ただし、結果画面で、全問題が「正解」してる状態で、 間違えた問題のみを選択すると、間違えてる問題がないため、 次の問題がなくなってしまうので、「1つでも、未回答か不正解」があるときだけ、 このリンクを表示する! にて、終了です。

回答No.19

> 再テスト機能の問題解決方法を教えて下さい。 おっけ~。 それと次ネタも了解~ ちょいお待ちを!

回答No.18

さてと~今週は、どこから攻めますか~?(週刊番組かっ!) 今、DIVのidが決め打ちになってるわけですが。 これをQAという疑似クラスに接続するDisplayクラスにしてみる? なんてのも、拡張ですよ!。 いつか、「グラフィカルで表示したい」、 テスト時は「テキストで表示したい」 って時、画面への表示を一つのモジュールで分けておけば、 そのユニットを入れ替えるだけで、完了! みたいに、楽に機能上げ下げ(いらない機能を取り外すのも大事!) なんてのも・・・ ってことで、今週、どこをいじりたいか教えてくださいね~

panja2021
質問者

補足

間違えた問題だけを再テストのリンクをクリックしたときに、 間違えた問題だけを全問正解するまで表示させる機能を追加するのに、 まだ悩んでいます。 提案なのですがそれが終わったらつぎのネタに入りませんか? EXCELからみのネタを考えましたから。 再テスト機能の問題解決方法を教えて下さい。 よろしくお願いします。

回答No.17

>変更点バッチしOKです。ありがとうございました。 質問者さん、いい人ですね~ 結構ね、一生懸命、書いてあげても見もしないで、 「ありがとうございました」で、板を閉じて終わりって事も 多いので^^私も楽しいです!。 -------------------------------------------- {q:"カタツムリを漢字で書くとどれ?",a:["禍牛","鍋牛","蝸牛","水星"],c:3}, c:3の"蝸牛"が答えになるはずが、4番めの"水星"になってしまいます。 まずここについて、「0オリジン」というのですが、 「3」という数字は、 0、1,2,3 「4番目」です。 "蝸牛"は、先頭から、0,1,2=3番目の「2」になります。 配列変数の先頭が「0」だという特性からこのズレが発生しています。 -------------------------------------------- まだネタがあるのですがどうですか? [ネタ] 最後のページに再テストの項目を追加したいです。 具体的には、間違えた問題だけを再テストのリンクをクリックしたときに、 間違えた問題だけを全問正解するまで表示させる機能を追加したいです、 案外!もう!質問者さん! いろんなことを理解されてる気がしますよ~ 判定で「正解/不正解」って出せているわけなので、 その部分をコピペして、次の問題の「過去の回答」が 正解を指していない物を出せばいいんですよ!。 一番最初は「過去の回答」はないですよね? =つまり!unknown==「正しい答えか」?はNOですからね。 なので、それをループさせれば、いいって事です。 次の問題の時、「すでに回答済み+正しいならスキップ」 って処理を追加すればいいのですよ。 しかし、全問正解するまでやったら、 TABLEで、正解/不正解教えたり CSV吐いたりする意味が、もうない気がする。。 =全部「正解」にしかならないのだから。。 当然最初引っ付いていた、保存関係も・・・ -------------------------------------------- で、この オブジェクト名.prototype.関数名 = function(パラメタ) { // } やり方、好き勝手に拡張しまくれるので、 <script src="quiz.js"> とかで、別ファイルにしちゃって、 HTMLには、DIVとかの表示部と、問題データ。 起動コード var test=new QA(問題データ); だけかけば、量産できますね。。 また、どの変数が何してたっけ?って事もないので、 全体が荒れないメリットもあります。 あと、今「回答の順番が常に同じ並び」 ってのも、違和感があるかと。。 それだと、位置を覚えたら終わりなので。 必ず「先頭の選択肢が正解」、続く「選択肢がすべて不正解」 で、それをシャッフルして、 「回答されたものが元々の配列の0番=正解」 のほうが、本格的かもですね! やるなら、そのうち書いてもいいんですけど^^ 金曜日なので、また、来週かな~ 質問者さんも、これで遊んでみてくださいね~ およそ、ゲームとしての基本フローと、 各関数が何をすべきで何を担当してるのか? がわかるようには、書いてみたつもりです。 例えば、restartって関数は、実質0を代入する事しかしてません。 でも、後からソースを見たら、 「0って何の意味なの?なんで0なの?」 になります。 しかし、関数名がrestartなら、 あ~「再度やる系の関数と初期化なのね!」 と、後から見てもわかる! という感じのイメージで作ってます。 また、その時、変数以外に画面の何かを書き換えたい? などがあっても、そこにいれればいいよね?と 拡張も簡単かと! ってな、コンセプトになってます~ では、よい週末を! 少しはお役に立てました?

panja2021
質問者

補足

>少しはお役に立てました? 少しどこかとても助かりました。 もうすこし深くソースコードを読んでみます。 >やるなら、そのうち書いてもいいんですけど^^ 金曜日なので、また、来週かな~ お暇なときでいいのでよろしくお願いします。 とても助かりました。 ありがとうございました。 私の力不足のときは、また来週お願いします、 ありがとうございました。

回答No.16

変更した分だけ・・・書きますね。 ------------- // コンストラクタ function QA(mondai_data) { this.mondai_data=mondai_data; this.mondai_no=0; this.user_answer=[]; this.clear(); } //表示物を消す QA.prototype.clear = function() { document.getElementById("text_q").innerHTML = ""; document.getElementById("text_s").innerHTML = ""; document.getElementById("text_n").innerHTML = ""; } //回答判断 QA.prototype.answer = function(user_answer) { //この問題の選択肢の数は自動判断(選択肢は何個でもOKです) var answer_count=this.mondai_data[this.mondai_no].a.length; if (user_answer>=answer_count) { // 通常あり得ないが選択肢よりも大きい回答が来た場合エラーとする document.getElementById("text_s").innerHTML = "error"; return; } // ユーザーが答えた回答を覚えておく this.user_answer[this.mondai_no]=user_answer; if (user_answer==this.mondai_data[this.mondai_no].c) { document.getElementById("text_s").innerHTML = "正解"; }else{ document.getElementById("text_s").innerHTML = "不正解 答えは" + this.mondai_data[this.mondai_no].a[this.mondai_data[this.mondai_no].c] + "でした"; } if (++this.mondai_no<this.mondai_data.length) { // 次の問題がまだある document.getElementById("text_n").innerHTML = "【<a href='javascript:test.next()'>次の問題へ</a>】"; }else{ // 次の問題はもうない→終了 document.getElementById("text_n").innerHTML = "【<a href='javascript:test.Kekka()'>結果発表</a>】"+ "【<a href='javascript:test.Csv()'>CSV出力</a>】"; } // このデータ類を保存したい場合→SaveDataToLocalStorage // 最後にまとめて保存なら、[終了]の部分にSaveDataToLocalStorageを入れればOK // 毎回保存したいなら、この位置にSaveDataToLocalStorageでもOKです。 console.log('[ユーザーの回答ログ]'); console.log(this.user_answer); } //次の問題へ QA.prototype.next = function() { this.clear(); this.quiz(); } //初めから QA.prototype.restart = function() { this.mondai_no=0; this.clear(); test.quiz(); } // 結果発表 QA.prototype.Kekka = function() { var mondai_max=this.mondai_data.length; var inner=""; // その他の表示物を消す this.clear(); inner="<table border='2'><caption>成績発表</caption><tr><th>問題</th><th>成績</th></tr>"; for (var mondai_index=0;mondai_index<mondai_max;mondai_index++) { inner+="<tr>"; inner+="<td>"+"問題"+(mondai_index+1)+"</td>"; var user_answer=this.user_answer[mondai_index]; if (user_answer !== undefined) { if (user_answer==this.mondai_data[mondai_index].c) { inner+="<td>正解</td>"; }else{ inner+="<td>不正解</td>"; } }else{ inner+="<td>未回答</td>"; } inner+="</tr>"; } inner+="</table>"; inner+="【<a href='javascript:test.restart()'>同じ問題を最初から</a>】"; document.getElementById("text_n").innerHTML = inner; } // CSV出力 QA.prototype.Csv = function() { // これ今は何もしてないので呼ぶ意味はない this.SaveDataToLocalStorage(); // ここしか使っていない this.CsvOutput(); } <script> /* ちょっと面倒ですが、常にaの先頭に答えを置いて、表示の時シャッフルすると、 * cのカラムが不要になる作り方もあります。 * cの値を0オリジンに変更しました。 */ const qa = [ {q:"イルカを漢字で書くとどれ?",a:["海豚","海牛","河豚"],c:0}, {q:"クラゲを漢字で書くとどれ?",a:["水浮","水母","水星"],c:1}, {q:"カタツムリを漢字で書くとどれ?",a:["禍牛","鍋牛","蝸牛"],c:2} ]; /* パラメーターに、問題データを渡してください */ test=new QA(qa); // test.set_mondai_no(2); /* 2番=3問目から開始 */ test.quiz(); </script> 同じパート(関数とか同じ行)をこれで上書きすればOKです!。 わけわからなくなったら、仕方ないので、 全部をまた、投稿してもOKですけど。 最初からは、成績発表にくっつけてますが。 好みで、どうぞ! 新しく3個のDIVの中身をクリアする.clear()というメソッドを入れてあり、 何時でも呼べば、まっさらになります!。 という事で、、どうでしょ?

panja2021
質問者

補足

変更点バッチしOKです。ありがとうございました。 -----------------//<解決できました。> 問題の選択肢を選んだときに正解と一致しないです。 コンソールには選んだ選択肢が正しく渡っています。 [ユーザーの回答ログ] mondai017.html:301 (3) [1, 1, 0] 配列の3番めの0が問題番号です、 選択したのは3番めの【3:蝸牛】を選択しまいしたが、 ----------------- 問題 3問目:カタツムリを漢字で書くとどれ? 選択 【1:禍牛】【2:鍋牛】【3:蝸牛】【4:水星】 解答 -------------------- 解答結果が不正解 答えは水星でした と表示されます。 選んだ選択肢【3:蝸牛】と結果の正解が「水星」と表示され一致しません。 問題 3問目:カタツムリを漢字で書くとどれ? 選択 不正解 答えは水星でした //この部分です結果は 解答 案内 【次の問題へ】 「問題点2」 それと問題点がもう一つあります。 解答の下に表示されるはずが「選択」の下に「答え」が表示されています。 「問題点1」 選択肢を選んだ番号には問題ありませんが、 表示された結果画面の「正解の表示」に間違いがあります。 {q:"カタツムリを漢字で書くとどれ?",a:["禍牛","鍋牛","蝸牛","水星"],c:3}, c:3の"蝸牛"が答えになるはずが、4番めの"水星"になってしまいます。 次はc:3をc:0に書き換えてみました。 {q:"カタツムリを漢字で書くとどれ?",a:["禍牛","鍋牛","蝸牛","水星"],c:0}, c:0に書き換えたら選んだ選択肢と正解が一致しました。 「問題点1」は解決できました。 「問題点2」が解決できていないです。 <h2>問題</h2> <div id="text_q"></div> <h2>選択</h2> <div id="text_s"></div>  //ここが問題の箇所だと思います。 <h2>解答</h2> <div id="text_a"></div>  //本当はここに解答結果が表示されるはずですが「text_s」に答えが表示されています。 <h2>案内</h2> <div id="text_n"></div> 問題点2は「text_s」を「text_a」に書き換えたら解決できました。 if (user_answer==this.mondai_data[this.mondai_no].c) { alert(user_answer+"正解"); document.getElementById("text_a").innerHTML = "正解"; //ここのtext_aの部分がtext_sになっていたのが問題でした。 }else{ alert(user_answer+"不正解"); alert(this.mondai_data[this.mondai_no].a[this.mondai_data[this.mondai_no].c]); document.getElementById("text_a").innerHTML = "不正解 答えは" + this.mondai_data[this.mondai_no].a[this.mondai_data[this.mondai_no].c] + "でした"; }  //ここのtext_aの部分がtext_sになっていたのが問題でした。 勉強になりました。ありがとうございました。 -------------------------- まだネタがあるのですがどうですか? [ネタ] 最後のページに再テストの項目を追加したいです。 具体的には、間違えた問題だけを再テストのリンクをクリックしたときに、 間違えた問題だけを全問正解するまで表示させる機能を追加したいです、 // 次の問題はもうない→終了 document.getElementById("text_n").innerHTML = "【<a href='javascript:test.Kekka()'>結果発表</a>】"+ "【<a href='javascript:test.Retry()'>再テスト</a>】"+ "【<a href='javascript:test.Csv()'>CSV出力</a>】"; } お体大事になさってください。お暇なときでいいのでよろしくお願いします。 頭の体操になりました。 ありがとうございました。

回答No.15

>お暇なときでいいのでよろしくお願いします。 はい! 久しぶりに楽しめてるので、全然OKですよ~ また、今書いてくれた「失敗」データ。 これかなり重要な情報で、これを見ることで 何がまずかったか?がすぐわかるので、無駄な手間が減って かなり!助かります! あと、問題の「数」無制限と、「選択肢」無制限も 拡張済みなので、色々あそんでみてくださいね! できれば href=javascript:,,,,, ってのを、aというタグをメモリ上に作って「クリックしたら」 と書きたいんですけどね。じゃないと、"test"って文字が 隠せない物で。(初めから言ってる手抜きの部分) そこ直せば、最悪永久に遊べるかも^^ですね。 最初セーブしてる部分があったので、何がしたいのか、 実は今でもわかってなくて、そこ削除しちゃってますが^^ ローカルストレージって使うのはいいんですが、 消すのが面倒なので、結構こちらでは「避けてます」 ってなことで、なかなか暇つぶし楽しめてますよ!。

回答No.14

まず、ここまではうごきましたか? >最後にテーブルで解答一覧表示を追加しようとしているのですけれども表示されません。 ふむふむ! 「//ここが問題の箇所だと思います。」 まずですが、デバッガーを使うといいですよ。 今のブラウザには、JavaScriptのデバッガーは内蔵されており 簡単に開発できるので、なれると、サクサク開発できますよ! for (n=0;n<qakey.length;n++) { s += "<tr><td>" + (n+1) + "</td><td>" + text_s+ "</td><tr>"; s += "<tr><td>" + (n+1) + "</td><td>" + this.user_answer+ "</td><tr>"; } 原因: 「this.user_answer」はarrayになります。 ですので、ループ自体をthis.user_answer.lengthの数回すほうがいいです。 入っている値は「ユーザーが答えた番号」になるので、 例えば2問目から開始すれば、1問目の値は、unknown です。 s += "【<a href='javascript:setReady()'>同じ問題を最初から</a>】"; これは、クラス内のmondai_noを先頭=つまり0に戻せばいいだけです。 なので、 クラス内に、 //問題番号の選択 QA.prototype.first = function() { this.mondai_no=0; this.quiz(); } とでも書いて、 s += "【<a href='javascript:test.first()'>同じ問題を最初から</a>】"; これで、初期化+クイズ問題の表示が行われます。 >お手数ですが最後によろしくお願いします。 別に最後じゃなくてもいいですよ(笑) 別に私暇つぶしなので、何とも思ってないので! 後、 s = "【<a href='javascript:history.back()'>前のページに戻る</a>】"; これは、ブラウザ遷移なので、これをやると、 覚えてるデータが全部消えるので、 「前のページに戻る」というよりは「クイズを終了」 とかの方がいいですね。 また、お気に入りなどで、そのページをいきなり開かれると、 history.back()=「前のページに戻る」ですが、前のページがない事が あり、何も起こらない=操作不可能になる!という問題があるので、 この場合は、urlを書いた方が安全だと思います。 また、質問者さん自身がすでにDOMを行っており、 JavaScript上で、HTMLコンテンツ自体を作り出しているので、 同じように「このクイズアプリ」そのものに、 タイトル画面や問題選択などの表示物を作る関数を 作れば、「全部1つのページで済んじゃうんじゃない?」ってのも ありですよ。アドレス遷移がない方が、 「アプリっぽくていいでしょ」(なんとなくですが) ってのもありますのでね。。 あと、そのうち・・・例えばですが・・・ 「回答時間10秒」->カウントダウンー>「タイムアップ」 自動的に不正解扱いとして、処理?とか 拡張もしやすいかと思いますよ。 なお、GoogleChromeのJavaScriptデバッガーはF12を押すだけででます。 後は、Sourcesをクリックして、デバッグしたいソースを表示 行番号をクリックするだけでブレイクポイント (その位置を処理しようとすると自動的に停止して、全変数が見れる) 「同じ問題を最初から」などを導線と言いますが、 後で、追加しておきますよ^^ んま~また、明日かな(w) (暇つぶしなのでそこは、ごめんね~) ひとまず、今のサンプルがどこでどんな動きしてるのかな~ で、遊んでもらえたらと思います。 あと、CSV出力も確認を! (正解/不正解は、いらなかったのに入れちゃいまして、それどうすれば消せるかなど、調べてみてもいいかもです)

panja2021
質問者

補足

お返事ありがとうございます。 csv出力はばっちしOKです。ありがとうございました。 最後のページで問題一覧表示できたのですが、値がこういう感じになります。 <table border='2'><caption>成績発表</caption><tr><th>問題</th><th>成績</th></tr><tr><td>1</td><td>[object HTMLCollection]</td><tr><tr><td>1</td><td>[object HTMLCollection]</td><tr><tr><td>1</td><td>1,1,1,1,1,1,1,1,1,1</td><tr><tr><td>2</td><td>[object HTMLCollection]</td><tr><tr><td>2</td><td>1,1,1,1,1,1,1,1,1,1</td><tr><tr><td>3</td><td>[object HTMLCollection]</td><tr><tr><td>3</td><td>1,1,1,1,1,1,1,1,1,1</td><tr><tr><td>4</td><td>[object HTMLCollection]</td><tr><tr><td>4</td><td>1,1,1,1,1,1,1,1,1,1</td><tr><tr><td>5</td><td>[object HTMLCollection]</td><tr><tr><td>5</td><td>1,1,1,1,1,1,1,1,1,1</td><tr><tr><td>6</td><td>[object HTMLCollection]</td><tr><tr><td>6</td><td>1,1,1,1,1,1,1,1,1,1</td><tr><tr><td>7</td><td>[object HTMLCollection]</td><tr><tr><td>7</td><td>1,1,1,1,1,1,1,1,1,1</td><tr><tr><td>8</td><td>[object HTMLCollection]</td><tr><tr><td>8</td><td>1,1,1,1,1,1,1,1,1,1</td><tr><tr><td>9</td><td>[object HTMLCollection]</td><tr><tr><td>9</td><td>1,1,1,1,1,1,1,1,1,1</td><tr><tr><td>10</td><td>[object HTMLCollection]</td><tr><tr><td>10</td><td>1,1,1,1,1,1,1,1,1,1</td><tr> これを<td>問題1</td><tr><tr><td>○</td>    <td>問題2</td><tr><tr><td>☓</td> と表示させたいです。 お暇なときでいいのでよろしくお願いします。

回答No.13

「パート2」 -------------------------------------- // 回答配列を[X問目、回答]の形式に変換し、それをCSV形式にした後、メインエレメントに接続 QA.prototype.CsvOutput = function() { var data = this.Final(); var text = this.ConvertArray2CSV(data); var blob = new Blob([text],{type: 'text/csv'}); var a = Object.assign( document.createElement('a'), { 'href':URL.createObjectURL(blob), 'download': 'test.csv', } ); document.body.appendChild(a); a.click(); a.remove(); } </script> <div id="text_q"></div> <div id="text_s"></div> <div id="text_n"></div> <script> /* ちょっと面倒ですが、常にaの先頭に答えを置いて、表示の時シャッフルすると、 * cのカラムが不要になる作り方もあります。 * cの値を0オリジンに変更しました。 */ const qa = [ {q:"イルカを漢字で書くとどれ?",a:["海豚","海牛","河豚"],c:0}, {q:"クラゲを漢字で書くとどれ?",a:["水浮","水母","水星"],c:1}, {q:"カタツムリを漢字で書くとどれ?",a:["禍牛","鍋牛","蝸牛"],c:2} ]; /* パラメーターに、問題データを渡してください */ test=new QA(qa); test.set_mondai_no(2); /* 2番=3問目から開始 */ test.quiz(); </script> -------------------------------------- 昨日からの変更点 test.set_mondai_no(2); /* 2番=3問目から開始 */ などで、問題の位置を指定できる機能を追加。 書かなければ自動的に先頭から。 最後の問題が終わると、「間違っていた回答」のみを 「X問目、"回答"] の順で、Arrayを作り、CSV形式に直した後、 ローカルダウンロードとして、出力可能に変更。 これで、一応やりたいことは全部、満たしたと思いますが。 いかがでしょうか? ただし、"test"という変数名しかまだ使えないです。 このサイトの投稿サイズの限界に引っかかるので、 一旦「このまま書き換えず」にそちらでファイル化して そこから、いじってみてください。 動く前に書き換えると、どこが悪いのかを探す手間が増えるだけなので! という事で、なかなか楽しめる問題でした! ありがとね!

関連するQ&A

  • JSON.stringifyで変換がうまくいかない

    var json = fs.readFileSync("./json.txt", 'utf8') //txtの中身は{Aiueo:[{hoge:"hoge"}]} console.log(JSON.stringify(json)); を実行しても、{"Aiueo":[{"hoge":"hoge"}]}にならず、"{Aiueo:[{hoge:"hoge"}]}"となります。 どうすれば解決できますか?

  • $.getJSONにJSON.stringifyを

    $.getJSONに、JSON.stringifyした結果を指定したいのですが、どうすればよいでしょうか? ■現状 ・コンソールにJSONは出力されているのですが、$.getJSONでこのファイルを指定しても、画面真っ白です ▼index.html <script type="text/javascript" src="hoge.json"></script> <script type="text/javascript"> $.getJSON('hoge.json', function(data) { ▼hoge.json var obj =([ [略], ]); var json_text = JSON.stringify(obj); // テスト出力 console.log(json_text); ■質問 ・$.getJSONにこの出力結果(json_text)を指定するためには、どうすれば良いでしょうか? ・一旦ファイル出力しなければいけないのでしょうか? ・どうやるのでしょうか? ・AJAXでサーバ側へデータを渡してファイル出力した後、$.getJSONでその出力したファイルを指定するしかない?

  • ローカルストレージがうまくいかない

    ローカルストレージを使って変数内のテキストを、保存してリロードしても削除するまで残るようにしたいのですがうまくいきません。 変数を指定してもダメで、テキストしか入れられないと聞いたのですがそうなのでしょうか? 下記のようにしても残ってくれません。 変数の中身を残すにはどうしたらいいでしょうか。 localStorage.getItem("onePrice"); var onePriceResult = document.getElementById('onePriceResult').innerHTML = あああ'; localStorage.setItem("onePrice", onePriceResult);

  • javascriptで困っています。教えてください

    html5でcanvasに描いた画像をsave_buttonを押してlocalStorageで保存して、それをload_buttonをおして読み込もうとしているのですが、うまくいきません。 canvas.toDataURL();でデータを6bit毎に分割できています。 それを保存して、 var base64 = window.localStorage.getItem("saveKey");で読み込むこともできています。 その後canvasに描画できません。 よろしくお願いします。 var canvas = document.getElementById("myCanvas"); $("#save_button").click(function () {    // Canvasからbase64エンコーディングされた画像データを取得する var canvas = document.getElementById("myCanvas"); var base64 = canvas.toDataURL(); // LocalStorageに保存する window.localStorage.setItem("saveKey", base64); }); $("#load_button").click(function () { // LocalStroageからデータを取得する var base64 = window.localStorage.getItem("saveKey"); // Imageオブジェクトを作成し、src属性にデータを設定する var image = new Image(); image.src = base64; image.onload = function(){ // 画像の読み込みが終わったら、Canvasに画像を反映する。 canvas.drawImage(image, 0, 0); } });

  • こちらのソースですが、なぜundefinedがでるのでしょうか?

    こちらのソースですが、なぜundefinedがでるのでしょうか? また、undefinedを消す方法はありますか? よろしくお願いいたします。 <script> window.onload = function(){ var hairetu = Array(1,2,3,4,5,6,7,8,9,10); for(var i=0; i<hairetu.length; i++){ var hoge; if(hairetu[i] % 2 == 0 && hairetu[i] % 3 == 0){ hoge += hairetu[i] + '\n'; }else if(hairetu[i] % 2 == 0){ hoge += hairetu[i] + '\n'; }else if(hairetu[i] % 3 == 0){ hoge += hairetu[i] + '\n'; }else { hoge += hairetu[i] + '\n'; } } alert(hoge); } </script>

  • javascriptで別ファイルで変数を取得する。

    A.htmlで入力した文字をB.htmlに出るようにしたいのですが、全然出ません。 アラートは表示されるのですが、入力欄に何を打っても、 namae と出てしまいます。変数に何も入ってないようです。 これを〔javascript〕って入力すれば、アラートに〔javascript〕って出るようにしたいのですが、どうしたらよろしいでしょうか? 〔A.html〕 <script type="text/javascript"> var val=namae; window.localStorage.setItem("result", val); </script> <form action="B.htm" id="form1" method="post" onsubmit="check()"> <p>名前<br><input type="text" name="namae" id="buttom" size="28" /></p> <input type="submit" value="送信"/> </form> 〔B.html〕 <script type="text/javascript"> var val = window.localStorage.getItem("result"); alert(val); </script>

  • 関数内での繰り返し処理の結果を配列で受け取りたい

    関数内でfor文で繰り返し処理を行い、 結果を配列として返すような関数を書きたいと思っています。 function hoge(){ var a = [1,2,3,4]; for (var i=0; i < a.length; i++){ a1 = "a" + i; var arr = new Array(); arr.push(a1); } return arr; } しかし、以下のように 関数hogeの結果を変数bで受け取ってみると、 配列の最後のデータしか表示されません。 var b = hoge(); alert(b); //a3のみが表示される a0, a1, a2, a3と表示されるようにするには、 どうしたらよいでしょうか。

  • JSの保存ダイアログについて

    以下のコードは簡易メモ的なものです そこに書き込まれた内容を保存できるようにしたいのですがfunction dl()には何を書けばいいのでしょうか? 調べてみて function dl(C:\){ var a = document.createElement('a'); a.href = C:\; a.setAttribute('dl', name || 'noname'); a.dispatchEvent(new CustomEvent('click')); } としてみたのですがこれを書き込むと保存ダイアログはおろかtextの保存もできなくなってしまいます <input type="text" id="title"><br><br> <textarea id="memo" rows="8" cols="50"></textarea><br><br> <input type = "button" value="SAVE" onclick="dl();"> <script> var title = document.getElementById("title"); var memo = document.getElementById("memo"); window.onload = function() { var body_title = localStorage.getItem("title"); if (body_title != null) title.value = body_title; var body_memo = localStorage.getItem("memo"); if (body_memo != null) memo.value = body_memo; } title.onchange = function() { localStorage.setItem("title",title.value); } memo.onchange = function() { localStorage.setItem("memo",memo.value); } function dl(){ } </script>

  • 複数のtextareaの保存について

    下記のコードのようにtextareaが二つあったとします id="a"は保存できましたがid="b"はどうやって保存するのでしょうか?("a", "b")としても無理でした どのようにすれば複数保存できるのでしょうか? ご回答お願いします <html> <head> </head> <body> <textarea id="a"></textarea> <textarea id="b"></textarea> <script> var a = document.getElementById("a"); window.onload = function() { var body = localStorage.getItem("a"); if (body != null){ a.value = body; } }; a.onchange = function() { localStorage.setItem("a",a.value); }; </script> </body> </html>

  • 配列内の値の取得について

    FlashBuilderです。 例1のようにすると問題なく取得できるのですが、 例2のようにするとobject,objectという値が返ってきてしまいます。 例2の配列内の値を参照するにはどのようにすれば、宜しいでしょうか? 例1: var myAry:Array=[]; myAry.push("a","b"); Alert.show(myAry[0]); 例2 var myAry:Array=[]; myAry.push({index:0, souce:"a"}); myAry.push({index:1, souce:"b"}); Alert.show(myAry[0]);

    • ベストアンサー
    • Flash

専門家に質問してみよう