Javascript初心者の勉強ログ（クイズゲーム編 後編）

前回（[Javascript初心者の勉強ログ（クイズゲーム編 前編）]()）の続きです。

# オリジナルを追加
さて、ここからが楽しいところ。
自分の好みにカスタマイズいたします。
やりたいことは以下の通り。

:::note info
1.　第何問目なのかを表示させる
2.　解答の正誤をページ内に表示させる
3.　次の問題に進むボタンを設置
4.　ページ下部に問題の解説を表示させる
:::
です！

一つずつ解決していきましょう〜！

## 1.　第何問目なのかを表示させる
クイズの問題文を表示させる時に使ったコードをアレンジすればいけそうだな、と思ったので
まずは、HTMLに表示させるためのpタグとダミーテキストを用意して
```HTML:HTML
<div class="question__wrapper">
      <!-- 何問目なのかを表示 -->
      <h2 id="js-questionNumber" class="question__number">
        第◯問
      </h2>
      <p id="js-questionText" class="question__text">
        text
      </p>
```
`setupQuiz`関数で問題文を表示させるようにしていたので、
そこにダミーテキストを書き換えるコードを追記してみました。
`setupQuiz`関数は以下のようになっています。
```javascript:javascript
// クイズの問題文、選択肢を定義
const setupQuiz = ()=> {

  // 何問目なのかを表示させる
  document.getElementById('js-questionNumber').textContent = '第' + (quizIndex + 1) +'問';

  // 問題文を表示させる
  document.getElementById('js-questionText').textContent = quiz[quizIndex].question;

  // 選択肢を表示させる
  let buttonIndex = 0;
  while(buttonIndex < buttonLength){
    $button[buttonIndex].textContent = quiz[quizIndex].answers[buttonIndex];
    buttonIndex++;
  }
}
```
## 2.　解答の正誤をページ内に表示させる
これもそう難しくはなさそうです。
まずは、HTMLに表示させるためのpタグを用意して
（今回は選択肢を選ぶ前は何も記載したくないのでテキストは入力していません）
```HTML:HTML
<div class="answer">
    <p id="js-answerResult" class="answer__result">
    </p>
  </div>
```
`clickHandler`関数のアラートで表示するようにしていたところを
ダミーテキストを取得して代入するように修正しました。
```javascript:javascript
// ボタンをクリックされたら正誤判定
const clickHandler = (e) => {
  if(quiz[quizIndex].correct === e.target.textContent){
    document.getElementById('js-answerResult').textContent = '正解です！';
    score++;
  }else {
    document.getElementById('js-answerResult').textContent = '不正解です！';
  }
}

let handlerIndex = 0;
while(handlerIndex < buttonLength){
  $button[handlerIndex].addEventListener('click', (e) => {
    clickHandler(e);
  });
  handlerIndex++;
};

// 次の問題に行く
// quizIndex++;

// if(quizIndex < quizLength){
//   // 問題があれば次の問題を表示
//   setupQuiz();
// }else {
//   // 問題がなければ終了
//   window.alert('終了！あなたの正解数は'+ score + '/' + quizLength + 'です！');
// }
```
次の問題に移動するコードは下に退避してコメントアウトしました。
こちらは後ほどいじります。

## 3.　次の問題に進むボタンを設置
「次の問題へ進む」ボタンを押したら次の問題が表示されるようにしたいので
HTMLを追加して...
```HTML:HTML
<button type="button" id="nextQuestion">次の問題へ進む</button>
```
と、ここで問題発生です。
buttonタグを使うと、これまでのbuttonタグの数やテキストを取得していたところに影響が出て、正常に表示されなくなってしまいました。

なのでHTMLの選択肢用のbuttonタグに新しくクラスを当てて
```HTML:HTML
<div class="question__options">
        <button type="button" class="question__item js-questionItem">選択肢１</button>
        <button type="button" class="question__item js-questionItem">選択肢2</button>
        <button type="button" class="question__item js-questionItem">選択肢3</button>
        <button type="button" class="question__item js-questionItem">選択肢4</button>
      </div>
```
`＄button`を定義していたところを修正しました。
```javascript:javascript
// 問題文を表示させる
const $button = document.getElementsByClassName('js-questionItem');
```
これで正しく問題文と選択肢が表示されるようになりました。

あとは先ほどコメントアウトした次の問題に行くためのコードを修正します。
ボタンをクリックしたら次の問題へ行くので
元のコードは`nextClick`関数に入れて
`js-nextQuestion`がついているボタンをクリックした時にその関数を呼び出す
という形にしました。
```javascript:javascript
// 「次の問題に進む」ボタンをクリックされたら次の問題に行く
const nextClick = (e) => {
  quizIndex++;

  if(quizIndex < quizLength){
    // 問題があれば次の問題を表示
    setupQuiz();
  }else {
    // 問題がなければ終了
    window.alert('終了！あなたの正解数は'+ score + '/' + quizLength + 'です！');
  }
}

document.getElementById('js-nextQuestion').addEventListener('click', (e) => {
  nextClick(e);
});
```

しかし、これだけだと最終問題でもボタンのテキストが「次の問題に進む」になってしまいます。
最終問題に行く時は「結果を見る」にしたいので、さらに条件を足します。

「最終問題へ行く時に」というのは、すなわち
「最終問題のひとつ前の問題の「次の問題に進む」ボタンを押した時に」と同義です。
つまり
「問題数（quizLength）-1」が今の問題（quizIndex）と同じになれば良いのですね。
あとは、その条件の時に「id="js-nextQuestion"（「次の問題に進む」ボタン）」のテキストを取得して「結果を見る」に書き換えればOKです。
```javascript:javascript
// 「次の問題に進む」ボタンをクリックされたら次の問題に行く
const nextClick = (e) => {
  quizIndex++;

  if(quizIndex === quizLength - 1){
    // 次の問題を表示
    setupQuiz();
    // 最終問題へ行く時に、「次の問題へ進む」ボタンのテキストを「結果を見る」に変える
    document.getElementById('js-nextQuestion').textContent = '結果を見る';
  }else if(quizIndex < quizLength){
   // 問題があれば次の問題を表示
    setupQuiz();
  } else {
```
## 4.　問題の解説を表示させる
あとは、正誤が出るだけだと味気ないので
解説文を入れたいと思います。
解説文を出すためにHTMLで見出しと場所を作って
```HTMl:HTML
<h2>解説</h2>
    <p class="answer__explanation"></p>
```
quizの配列の中に解説文を追加
```javascript:javascript
const quiz = [
  {
    question: '見出しを意味するタグはどれ？',
    answers: [
      'title',
      'h1',
      'span',
      'div'
    ],
    correct: 'h1',
    // 解説
    explanation: '見出しは「heading」なので「h1」が正解。'
  },{
    question: 'ブロック要素はどれ？',
    // 以下略
```
選択肢を選んだ後に解説文を出したいので、
正誤判定をしている`clickHandler`の中に処理を追記します。
```javascript:javascript
// ボタンをクリックされたら正誤判定
const clickHandler = (e) => {
  if(quiz[quizIndex].correct === e.target.textContent){
    document.getElementById('js-answerResult').textContent = '正解です！';
    score++;
  }else {
    document.getElementById('js-answerResult').textContent = '不正解です！';
  }
  // 解説文を表示
  document.getElementById('js-answerExplanation').textContent = quiz[quizIndex].explanation;
}
```
あとは次の問題に移動した時に、表示されている解説文と正誤判定の文を消したいので
`nextClick`の`setupQuiz`の前に処理を書きます。
```javascript:javascript
// 「次の問題に進む」ボタンをクリックされたら次の問題に行く
const nextClick = (e) => {
  quizIndex++;

  if(quizIndex < quizLength){
    // 問題があれば解説文を消して次の問題を表示
    document.getElementById('js-answerExplanation').textContent = '';
    setupQuiz();
  }else {
```
これで、解答したら解説まで読めるようになりました！
全体のコードはこちらをご参考ください
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ExpNoOX" data-user="n-ogata" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/n-ogata/pen/ExpNoOX">
  Untitled</a> by nao (<a href="https://codepen.io/n-ogata">@n-ogata</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## まとめ
とりあえず今回は機能が動けばOKということで
見た目は残念だし、問題数は3問と少ないのですが
今後学習を進める中で、もっとリッチに仕上げていきたいですね。

JSのコードも、見る人が見ればもっとスマートにかけるのではないかな〜と思っています。
「こう書いた方がもっと良くなるよ〜」と、アドバイスがある方は
ぜひコメントいただけると、私が大変喜びます！！

コーディングに関する記事を書いたのが初めてで
読みにくい点もあったかと思いますが、
最後まで見ていただいて本当にありがとうございますmm