Webアプリでクイズを作ろう ~後半:動きをつける2~

プログラミング

こんにちはるりです。

今回は、前回に続きJavaScriptでページに動きを付けていきます。
前回の記事では問題の出題ページを完成させましたので、今回は正解ページ不正解ページリザルトページを作って聞こうと思います。
基本的な仕組みは前回の記事で解説したので、詳しく知りたい方はそちらをご覧ください
Webアプリでクイズを作ろう ~後半:動きを付ける1~

動きを付ける

正解ページ・不正解ページ

正解ページと不正解ページを別に書きましたが、どちらも仕組み自体はほとんど変わらないので正解ページをベースに書き、違うところをつけ足していきます。

まずはコードを見てください。

const result = [
    {
        answer: "a",
        explanation: "アルファベットの並び順は「a b c d e f g h i ...」"
    }, {
        answer: "か",
        explanation: "平仮名の並び順は「あ い う え お か き く ...」"
    }
];

const answerLength = result.length;
const questionPage = "question.html";
const resultPage = "result.html";
const $next = document.getElementById("btn-next");
const $answer = document.getElementById("answer-text");
const $explanation = document.getElementById("explanation");
let resultCount = 0;

//セッションストレージから変数を呼び出す
const loadCount = () => {
    if(sessionStorage.getItem("countNumber")) {
        resultCount = sessionStorage.getItem("countNumber");
    }
}
loadCount();

//セッションストレージに変数を保存
const saveCount = () => {
    sessionStorage.setItem("countNumber", resultCount);
}

const setAnswers = () => {
    $answer.textContent = "答えは:「" + result[resultCount].answer + "」";
    $explanation.textContent = result[resultCount].explanation;
}
setAnswers();

//「次へ」を押したときに問題ページへ飛ぶ
$next.addEventListener("click", () => {
    if(resultCount < answerLength - 1) {
        resultCount++;
        saveCount();
        document.location.replace(questionPage);
    } else {
        document.location.replace(resultPage);
    }
})

正答と解説

このページには、「正答」「問題の説明」の2つを表示します。
ですので、この2つを“result”というオブジェクトに入れています。
この時、元々準備していた問題と同じ順番に用意します。上から順番に表示しますので、問題と違った順番でオブジェクトに格納すると一致しなくなります。

変数・定数

11~17行目で今回使う変数と定数を定義しています。
どこで使うかは各々の所で説明しますが、上から「resultオブジェクトの要素数」 「クイズ出題ページのHTMLファイル(のURL)」 「結果画面のHTMLファイル(のURL)」 「’次へ’ボタンのドキュメントを取得するオブジェクト」 「’answer-text’のドキュメントを取得するオブジェクト」「’explanation’のドキュメントを取得するオブジェクト」 「ストレージから呼び出したものを格納する変数」です。
20~24行目は「ストレージから変数を呼び出す」という関数を格納した定数、28~30行目は「ストレージに変数を保存する」という関数を格納した定数です。まだ定数に入っただけなのでまだ実行はしてません。

それぞれの詳しい仕組みは前回の記事で説明していますので、そちらをご覧ください。
Webアプリでクイズを作ろう ~後半:動きをつける1~

ストレージから変数を呼び出す

まずは何個目の正答・説明を表示するかを判定する変数をストレージから呼び出します。(“sessionStorage.getItem(‘ ‘)”)
画面にドキュメントを表示するよりも先に変数を呼び出しておかないと問題と違った答えが表示されてしまいますので、一番先にこれを行います。

正答・解説を表示する

32~35行目は、答えと解説文を表示するブロックにそれぞれ“result”に格納されているドキュメントを表示します。このとき、先ほど用意した変数「”answer”」「”explanation”」を使っています。35行目までで関数を定義し、36行目で実行してます。

ページの遷移

39行目以降で、「次へ」のボタンを押したときの動作を定義しています。

今回はパターンが2つあります。1つ目は「問題ページへ飛び次の問題を表示する」、2つ目は「結果画面へ飛び、結果を表示する」です。
これらはif文を使って判定します。

今 表示している正答・解説の順番がresultオブジェクトの要素数より少なければクイズ出題ページに飛び次の問題を出題します。(“resultCount < answerLength – 1“)
この時、43行目でページ遷移をする前に、41行目で

最後の正答・解説を表示しているときは、次の問題が無いので結果画面に飛び結果を表示します。

今回の説明は正解をしたときのページですが、不正解だった時のページも同じ仕組みです。
なので説明は省略します。

結果画面

最後に結果画面です。

const restart = document.getElementById("restart");
const questionPage = "question.html";

let score = sessionStorage.getItem("score");
let length = sessionStorage.getItem("length");

//点数を表示する
document.getElementById("result").textContent = "あなたのスコアは " + score + " / " + length + "点";

//「最初に戻る」を押したときに最初のページに飛ぶ
restart.addEventListener("click", () => {
    document.location.replace(questionPage);
})

//各変数をセッションページに0にリセット
const resetAny = () => {
    sessionStorage.setItem("quizNumber", 0);
    sessionStorage.setItem("score", 0);
    sessionStorage.setItem("countNumber", 0);
}
resetAny();

変数・定数

ここでも先ほどと同じく定数・変数を定義していきます。

「’最初に戻る’ボタンのドキュメントを取得」「問題出題ページのHTMLファイル(のURL)」「点数」「問題の総数」

点数を表示する

“result”のIDがついたブロックに点数を表示していきます。
変数“score”には正解数を、“length”には問題の総数がストレージから呼び出し格納されていますので、score / lengthとすることで何問中何問正解したかが分かりやすく表示できます。

ボタンの動作

11~13行目で、「最初に戻る」ボタンを押した時の動作を定義しています。
こちらも詳しくは前回の記事をご覧ください。

ストレージの初期化

最後にストレージに格納されている変数を初期化します。

今回使っている変数はタブを閉じればリセットされますが、もし連続して解く場合は点数が10になったりなど限界突破してしまいます。
ですので、16行目~20行目でストレージに保存されている変数をすべて0にしています。(21行目で実行)

こうすることで連続して問題を解いても点数が限界突破することがありません。

終わり

どうでしたでしょうか。
クイズをすべて作り終えました。

問題を変えてカテゴリーごとにクイズを作っても面白いかもしれません。
簡単に作れますので是非作って楽しんでみてください。

自分なりに分かりやすいように書いたつもりですが、語彙力が拙い故分かりにくいところがあるかと思います。
コメントやTwitterのDMで質問等いつでも受け付けていますので、遠慮なくご質問ください。

また別の記事でお会いしましょう。

それではまた

コメント