質問: 13 ) { if($(this).val()==data[count][3]){ alert("正解"); count++; start(); }else{ alert("不正解"); } } }); ### 試したこと 課題に対してアプローチしたことを記載してください ### 補足情報(言語/FW/ツール等のバージョンなど) より詳細な情報
回答: ### (余談)質問の仕方について すでに追記依頼されている通り、このような質問をする際はHTMLと変数定義部分をつけてください。 もしかするとHTMLにあなたのものすごいアイデアが入っていたり、変数定義部分に多大な苦労をしてつくった問題文が含まれているのかもしれません。 しかし、答えが欲しいのであれば気軽に問題を見て答えられるようにすることはとても有用で、このサイトでは推奨されています。 今後は現在の問題が再現できるコードを新たに作って質問するくらいのことはしましょう。 面倒でしょうが、回答者もそんな苦労はしたくない人が多いのです。 ### 本題 とりあえず、HTMLと変数定義部分を補い、さらに2問目以降もうまく動くようにしたコードを示します。 ``` Test 問題: ``` #### 説明 元のコードの問題は、キー処理を設定する対象のinput要素がstart関数内のjQuery.fn.htmlによって問題ごとに作成されているにも関わらず、キーイベントのハンドラ設定が一度しか行われていないことにあります。 ``` $("#ans").keypress(function(e){/* 処理 */}); ``` と書くと、ansというidの要素でキーが押された時に`/* 処理 */`が実行されるようになると考えているのだと思いますが、そうではありません。 「ansというidの要素」ではなく、「**このコードが書かれている場所で**idがansである要素」にイベントハンドラは設定されます。 質問のコードでこれが書かれている場所は、はじめの問題を表示するためにstart関数が実行された直後です。 ここでansというidである要素、というのに該当するのは1問目の解答欄のみで、2問目以降の解答欄は「キーイベント処理の後で実行されたstart関数のあと」という別の場所のものです。 だから、2問目以降でキーイベントのハンドリングができないのです。 jQueryはCSSになれた人が使いやすいように宣言的的な書き方ができるという性質がありますが、それゆえに宣言的に書けると思ってしまうことがしばしばあります。これはよくある間違いなのでよく考えて理解し、乗り越えていってください。 ### おまけ こうするのは面倒ですね。 また、解答欄を問題のついでに書き換わる部分に置くようなコードはあまり見かけません。 そこで、解答欄を出したり消したりするのにはjQueryのhide showなどを使う方法を提案してみます。 ``` Test 問題: = ``` このコードはアクセシビリティ(あらゆる人に使えるようになっているかという点。ここではスクリーンリーダーや点字ディスプレイ利用者、キーボード以外の入力デバイスの利用者など)の観点から言うと良くありません。 think49さまの2017/11/08 12:00のコメントにある通り、 問題をHTMLに書いておくか、問題を隠したいならサーバサイドスクリプトなどページ遷移を伴う方法を代替として提供するかするのが良いです。 #### 補足 think49さまの指摘もあり、確かに説明不足だと思ったので補足します。 > > こうするのは面倒で、 > > > イベントハンドラの設定を毎回作り直した要素について行い直すのは、記述の位置がその要素を作った場所になることによって、コールバック地獄を悪化させる恐れがあります。これが「面倒」なことです。 >また、解答欄を問題のついでに書き換わる部分に置くようなコードはあまり見かけません。 フォームを隠しておきたいときにinnerHTMLやjQuery.fn.htmlでフォームを出すのはそう見かけないと思います。 アニメーションを入れるため、とか、tabindexを適切に設定してアクセシビリティを向上させたいから、とか、理由はいろいろあるのでしょう。 あまり見かけないコードは読む人(未来の自分を含む)を混乱させるので、よくある書き方をした方が良いのではないでしょうか。 > > アクセシビリティ > > > hide/showはdisplay属性をいじります。これで要素を出したり隠したりすると、スクリーンリーダーがうまく対応しないということが考えられると思います。最近ではaria-hidden属性を使ってスクリーンリーダー向けにも隠された要素と明示することが広まりつつあると思います。 とはいえ、キーイベントを使った回答受付やjQuery.fn.htmlを使った問題文の更新という作りが、そういった方々への対応を考えたものとなっていません。 (いくらか編集しています。(あとから読む方へ)編集内容は投稿日時の下、編集日時のところにリンクがあるはずです。)