javascriptのif文やWhile文、配列を使うと、簡単なクイズゲームも作成できます。
今回は上記の画像のような簡単なクイズコンテンツの作成方法を紹介します。
クイズコンテンツを作成できる全体のコードは次のとおりになります。
▢HTML
<section class="quiz_box">
<div class="answer_correct"><div class="maru"></div></div>
<div class="answer_incorrect"><div class="batu"></div></div>
<div class="answer_result">
<h2 class="answer_result_title">結果発表!</h2>
<div class="answer_result_text"></div>
</div>
<div class="question_number" id="js-number"></div>
<h2 class="question" id="js-question"></h2>
<div class="answer_box">
<button class="answer" class="js-answer"></button>
<button class="answer" class="js-answer"></button>
<button class="answer" class="js-answer"></button>
<button class="answer" class="js-answer"></button>
</div>
</section>
▢CSS
.quiz_box {
position: relative;
width: 800px;
background-color: #fdde98;
margin: 0 auto;
margin-top: 40px;
}
.quiz_box .answer_correct {
position: absolute;
top: 0px;
left: 0px;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background-color: #e1e1e1;
visibility: hidden;
opacity: 0;
transition: all 0.5s;
}
.quiz_box .answer_correct .maru {
width: 100px;
height: 100px;
border-radius: 50%;
border: solid 10px red;
}
.quiz_box .answer_incorrect {
position: absolute;
top: 0px;
left: 0px;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background-color: #e1e1e1;
visibility: hidden;
opacity: 0;
transition: all 0.5s;
}
.quiz_box .answer_incorrect .batu {
position: relative;
width: 100px;
height: 10px;
background-color: blue;
}
.quiz_box .answer_incorrect .batu::before {
position: absolute;
width: 100px;
height: 10px;
background-color: blue;
content: "";
}
.quiz_box .answer_result {
position: absolute;
top: 0px;
left: 0px;
background-color: #fdde98;
width: 100%;
height: 100%;
visibility: hidden;
opacity: 0;
transition: all 0.5s;
}
.quiz_box .answer_result .answer_result_title {
text-align: center;
padding-top: 10px;
padding-bottom: 10px;
border-bottom: solid 1px #a0a0a0;
font-size: 24px;
}
.quiz_box .answer_result .answer_result_text {
padding: 50px;
font-size: 18px;
font-weight: bold;
}
.quiz_box .active_answer {
visibility: visible;
opacity: 0.8;
}
.quiz_box .active_result {
visibility: visible;
opacity: 1;
}
.quiz_box .question_number {
text-align: center;
padding-top: 10px;
padding-bottom: 10px;
border-bottom: solid 1px #a0a0a0;
font-weight: bold;
}
.quiz_box .question {
text-align: center;
font-weight: bold;
margin-top: 15px;
margin-bottom: 15px;
}
.quiz_box .answer_box {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin: 0 auto;
margin-top: 10px;
margin-bottom: 10px;
padding-bottom: 40px;
width: 400px;
}
.quiz_box .answer_box .answer {
border: solid 1px #000000;
width: 40%;
margin-top: 20px;
margin-right: 10px;
margin-left: 10px;
padding: 10px;
cursor: pointer;
}
▢JavaScript
const quiz = [
{
questionNumber: '質問1',
question: '免許センターがある市は?',
answers: [
'a.鴻巣',
'b.戸田',
'c.熊谷',
'd.深谷',
],
correct: 'a.鴻巣'
},
{
questionNumber: '質問2',
question: '高校受験前に受けるテストは?',
answers: [
'a.北辰テスト',
'b.南辰テスト',
'c.東辰テスト',
'd.西辰テスト',
],
correct: 'a.北辰テスト'
},
{
questionNumber: '質問3',
question: 'シラコバトをモチーフにしたマスコットキャラは?',
answers: [
'a.コバコバ',
'b.シラバト',
'c.コバトン',
'd.シラコン',
],
correct: 'c.コバトン'
},
]
let quizCount = 0;
const quizLength = quiz.length;
let score = 0;
const $button = document.querySelectorAll('.answer');
const buttonLength = $button.length
const setupQuiz = () => {
document.getElementById('js-question').textContent = quiz[quizCount].question
document.getElementById('js-number').textContent = quiz[quizCount].questionNumber
let buttonCount = 0;
while (buttonCount < buttonLength) {
$button[buttonCount].textContent = quiz[quizCount].answers[buttonCount]
buttonCount++;
}
}
setupQuiz();
let clickedCount = 0;
while (clickedCount < buttonLength) {
$button[clickedCount].addEventListener("click", function () {
const clickedAnswer = event.currentTarget
const answerCorrect = document.querySelector('.answer_correct');
const answerIncorrect = document.querySelector('.answer_incorrect');
const answerResult = document.querySelector('.answer_result');
const answerResultText = document.querySelector('.answer_result_text')
if (quiz[quizCount].correct === clickedAnswer.textContent) {
answerCorrect.classList.add("active_answer")
setTimeout (function(){
answerCorrect.classList.remove("active_answer")
}, 1000);
score++;
}
else {
answerIncorrect.classList.add("active_answer")
setTimeout (function(){
answerIncorrect.classList.remove("active_answer")
}, 1000);
}
quizCount++;
if (quizCount < quizLength) {
setTimeout (function(){
setupQuiz();
}, 1000);
}
else {
answerResult.classList.add("active_result")
answerResultText.textContent = '終了!あなたの正解数は' + score + '/' + quizLength + 'です!'
}
});
clickedCount++;
}
では詳しくコードの内容を解説します。
「配列にクイズ内容を格納する」→「クイズを表示する」→「クリックイベントを作成する」→「○×の判定を設定する」→「次のクイズを表示する」→「結果発表を表示する」という順に説明します。
const quiz = [
{
questionNumber: '質問1',
question: '免許センターがある市は?',
answers: [
'a.鴻巣',
'b.戸田',
'c.熊谷',
'd.深谷',
],
correct: 'a.鴻巣'
},
{
questionNumber: '質問2',
question: '高校受験前に受けるテストは?',
answers: [
'a.北辰テスト',
'b.南辰テスト',
'c.東辰テスト',
'd.西辰テスト',
],
correct: 'a.北辰テスト'
},
{
questionNumber: '質問3',
question: 'シラコバトをモチーフにしたマスコットキャラは?',
answers: [
'a.コバコバ',
'b.シラバト',
'c.コバトン',
'd.シラコン',
],
correct: 'c.コバトン'
},
]
まずはクイズの内容を変数の配列に格納します。配列には質問番号、質問タイトル、選択肢、答えを入れています。
質問番号、質問タイトル、選択肢は後にjavascriptを使ってHTML要素に代入します。答えはif文の条件分岐の判定で使います。
let quizCount = 0;
const quizLength = quiz.length;
let score = 0;
const $button = document.querySelectorAll('.answer');
const buttonLength = $button.length
/*クイズの設置 */
const setupQuiz = () => {
document.getElementById('js-question').textContent = quiz[quizCount].question
document.getElementById('js-number').textContent = quiz[quizCount].questionNumber
let buttonCount = 0;
while (buttonCount < buttonLength) {
$button[buttonCount].textContent = quiz[quizCount].answers[buttonCount]
buttonCount++;
}
}
setupQuiz();
クイズの質問番号と質問タイトル、選択肢を表示する方法を紹介します。
let quizCount = 0;
const quizLength = quiz.length;
let score = 0;
document.getElementById('js-question').textContent = quiz[quizCount].question
document.getElementById('js-number').textContent = quiz[quizCount].questionNumber
まずは配列の最初にあるクイズの質問番号と質問タイトル、選択肢を表示させます。
document.getElementByIdで、HTMLに記述したID「js-question」と「js-number」を取得。そしてtextContentを使って、この2つのID属性のHTML要素に、変数の配列に格納したクイズの番号と質問内容を代入します。
変数:quizCountは後にwhile文のループ、複数のクイズを順に表示させるためのカウント用の変数です。変数:scoreは後に「何問正解したか?」の数を表示させるためのカウント用の変数です。
これで一番最初の質問の質問番号と質問内容は表示できます。
let buttonCount = 0;
const $button = document.querySelectorAll('.answer');
const buttonLength = $button.length
while (buttonCount < buttonLength) {
$button[buttonCount].textContent = quiz[quizCount].answers[buttonCount]
buttonCount++;
}
質問の選択肢であるanswerクラスをdocument.querySelectorAllで取得して変数に格納します。
そしてwhile文では(選択肢の数だけ処理を実行する)という条件を設置しています。これにより選択肢の数だけ、選択肢のテキストがHTML要素に代入されて、選択肢が表示されるようになります。
const setupQuiz = () => {
【省略】
}
setupQuiz();
クイズの番号、質問内容、選択肢をこれまで表示させてきましたが、これらの一連の記述は後の記述でも使います。同じ記述を繰り返すのは面倒なので関数に格納します。
格納したら上記の記述のように「(呼び出したい関数)();」で関数を呼び出しましょう(上記の記述ではsetupQuiz();)。
let clickedCount = 0;
while (clickedCount < buttonLength) {
$button[clickedCount].addEventListener("click", function () {
【省略:if文】
clickedCount++;
}
今回はクリックで起きるクイズコンテンツを作成しているので、javascriptのクリックイベントを使います。「.addEventListener(“click”」という記述がクリックイベントを設置できる記述です。こちらもwhile文の繰り返し処理で、すべての選択肢にクリックイベントが適用できるようにしています。
今回、作成するクイズコンテンツには正解したら「○」を表示して、間違っていたら「×」を表示させています。こちらは下記の記述で実装しています。
const clickedAnswer = event.currentTarget
const answerCorrect = document.querySelector('.answer_correct');
const answerIncorrect = document.querySelector('.answer_incorrect');
if (quiz[quizCount].correct === clickedAnswer.textContent) {
answerCorrect.classList.add("active_answer")
setTimeout(function () {
answerCorrect.classList.remove("active_answer")
}, 1000);
score++;
}
else {
answerIncorrect.classList.add("active_answer")
setTimeout(function () {
answerIncorrect.classList.remove("active_answer")
}, 1000);
}
quizCount++;
○×の判定にはif文を使います。今回、if文で設定している条件は「quiz[quizCount].correct」と「clickedAnswer.textContent」になります。
変数:clickedAnswerに格納されているのが「event.currentTarget」。event.currentTargetはイベントが発生した対象の要素を取得できる記述になります。
今回はクリックした対象、つまりクリックした選択肢のボタンの要素をevent.currentTargetで取得しています。そして「quiz[quizCount].correct」はクイズの答えになります。
そのためクリックイベントで対象になった選択肢のテキストが、クイズの答えと一致しているか?がif文の条件になっています。
条件は設定したので、次は条件以降の処理を実装します。処理の内容は「クリックした選択肢が質問の答えと一致していたら○を表示する、一致していなかったら×を表示する」です。
「answerCorrect」は○を表示する、「answerIncorrect」は×を表示するHTML要素が格納されている変数です。これらはCSSで非表示に設定しています。
そして処理の内容は「answerCorrect.classList.add(“active_answer”)」「answerIncorrect.classList.add(“active_answer”)」という記述で実装しています。
「active_answer」というクラスは、非表示になっているHTML要素を再表示させるために用意したクラスです。これで○×が表示されるようになりました。
○と×は表示したままではなく、非表示にして次の問題の画面に移らなくてはなりません。ただ同じタイミングで非表示に設定すると、表示と非表示が打ち消し合ってしまいます。そこで時間差を利用して、○と×を非表示にする設定をします。
setTimeout(function () {
answerCorrect.classList.remove("active_answer")
}, 1000);
時間差で処理を実行するにはsetTimeoutを使います。これによって処理の実行を遅延させられます。時間は1000ミリ秒、1秒で処理時間を遅らせています。
quizCount++;
if (quizCount < quizLength) {
setTimeout(function () {
setupQuiz();
}, 1000);
}
○×を非表示にしたら、次のクイズを表示させます。
○×判定の処理が終わったら、クイズの数をカウントする用の変数「quizCount」の数値を増やして、クイズの総数である「quizLength」の数値を比較するifを記述します。
setupQuiz();とはさきほど作成したクイズを設置するための関数です。これにより「解いたクイズの数がクイズの総数よりも少ない場合は、次のクイズを設置する」といった処理を行えます。
すべてのクイズの回答を完了した後には、結果発表の表示も必要です。上記の結果発表の画面は下記のコードで実装しています。
const answerResult = document.querySelector('.answer_result');
const answerResultText = document.querySelector('.answer_result_text')
【省略】
else {
setTimeout(function () {
answerResult.classList.add("active_result")
answerResultText.textContent = '終了!あなたの正解数は' + score + '/' + quizLength + 'です!'
}, 1000);
}
answerResultは結果表示の画面を表示、answer_result_textは結果表示のテキストを表示するHTML要素を格納した変数です。結果表示の画面はCSSで非表示に設定していますが、「active_result」を付与することで結果表示の画面を表示できるようにしています。
GIV株式会社は、埼玉県川越市にあるWEB(ホームページ)制作会社です。お困りごと、ご相談、お気軽にご連絡ください。お問い合わせは、こちらから。