見出し画像

[JavaScript] はじめてのJavaScript その4

こんにちは。tomoです。
今日も今日とてクイズアプリ作成のつづき。

前回までのあらすじ

画面遷移はするようになったけれども、まだクイズには答えられない。
相変わらずボタンがダサい。

初回

前回

ということで今回はクイズに答えられるようにする部分の実装からですね。

ざっくり作る④ クイズ → 結果画面

クイズに答えられるということはアプリの挙動で言うと「選択肢が押されたときに正誤表示を出来る」ということになります。なので前回のボタン押下による遷移同様、選択肢が押された際に結果画面が表示される部分を実装すればよいと考えられます。

画像1

気を付けるべきは正解したときと間違ったときで表示すべき画面が(画像だけでなくボタンも)変わってくるので、その分岐を考慮する必要があります。

選択肢の各ボタンに正解/不正解のイベントを実装していくと下のようになります。
ちなみに次の問題を表示するボタンとスタートボタンを共有していて、ボタンに表示される文字を変える必要があるのでこの部分もJavaScriptに追加しています。

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>クイズ</title>
<link rel ="stylesheet" type="text/css" href="css/style.css">
</head>
<body bgcolor="aliceblue">
<label id="message"></label>
<div id="image-area">
   <img id='image' alt='character image'>
</div>
<div id='button-area'>
   <div id='options'>
       <button id='option1' style='grid-row: 1; grid-column: 1'>0.001 dL</button>
       <button id='option2' style='grid-row: 1; grid-column: 2'>0.01 dL</button>
       <button id='option3' style='grid-row: 1; grid-column: 3'>0.1 dL</button>
       <button id='option4' style='grid-row: 2; grid-column: 1'>10 dL</button>
       <button id='option5' style='grid-row: 2; grid-column: 2'>100 dL</button>
       <button id='option6' style='grid-row: 2; grid-column: 3'>1000 dL</button>
   </div>
   <button id='to-next'></button> <!-- スタート を削除 -->
</div>
<div id='to-title-area'>
   <button id="to-title">タイトルにもどる</button>
</div>
<script type="text/javascript" src="js/script.js"></script>
</body>
</html>

script.js

function changeMessage(next) {
   var message = document.getElementById('message');
   message.innerHTML = (next == 'quiz')      ? '1Lは何dL?'
                     : (next == 'correct')   ? 'せいかい!'        /* 正解時のメッセージを追加 */
                     : (next == 'incorrect') ? 'ざんねん・・・。'   /* 不正解時のメッセージを追加 */
                     :                         '単位のクイズ!';
}

function changeImage(next) {
   var image = document.getElementById('image');
   image.src = (next == 'quiz')      ? 'images/question/005.png'
             : (next == 'correct')   ? 'images/correct/000.png' /* 正解時の画像を追加 */
             : (next == 'incorrect') ? 'images/mistake/003.png' /* 不正解時の画像を追加 */
             :                         'images/title/003.png';
}

function changeButtonArea(next) {
   var startButton = document.getElementById('to-next');
   var options = document.getElementById('options');

   switch (next) {
       case 'quiz':
           startButton.style.display = 'none';
           options.style.display = 'grid';
           break;
       case 'correct': /* 正解の時のボタン表示操作を追加 */
           startButton.style.display = 'inline';
           startButton.innerHTML = 'つぎの問題';
           options.style.display = 'none';
           break;
       case 'incorrect': /* 不正解の時のボタン表示操作を追加 */
           startButton.style.display = 'none';
           options.style.display = 'none';
           break
       default: // title
           startButton.style.display = 'inline';
           startButton.innerHTML = 'スタート'; /* タイトル表示時は「スタート」 */
           options.style.display = 'none';
           break;
   }
}

function showTitle() {
   changeMessage('title');
   changeImage('title');
   changeButtonArea('title');
}

function showQuiz() {
   changeMessage('quiz');
   changeImage('quiz');
   changeButtonArea('quiz');
}

/* 引数に正解(true)/不正解(false)を取る関数を作成 */
function showResult(answer) {
   result = (answer == true) ? 'correct'
                             : 'incorrect'
   changeMessage(result)
   changeImage(result)
   changeButtonArea(result)
}

window.onload = function() {
   var startButton = document.getElementById('to-next');
   startButton.addEventListener('click', function() {
       showQuiz();
   });

   var titleButton = document.getElementById('to-title');
   titleButton.addEventListener('click', function() {
       showTitle();
   });

   /* 選択肢(option1~6)に結果画面への遷移イベントを追加 */
   var option1 = document.getElementById('option1');
   option1.addEventListener('click', function() {
       showResult(false); /* 間違った答えを選択 */
   })
   var option2 = document.getElementById('option2');
   option2.addEventListener('click', function() {
       showResult(false); /* 間違った答えを選択 */
   })
   var option3 = document.getElementById('option3');
   option3.addEventListener('click', function() {
       showResult(false); /* 間違った答えを選択 */
   })
   var option4 = document.getElementById('option4');
   option4.addEventListener('click', function() {
       showResult(true); /* 正解を選択 */
   })
   var option5 = document.getElementById('option5');
   option5.addEventListener('click', function() {
       showResult(false); /* 間違った答えを選択 */
   })
   var option6 = document.getElementById('option6');
   option6.addEventListener('click', function() {
       showResult(false); /* 間違った答えを選択 */
   })

   showTitle();
}

これで一通りスタートから結果までの遷移を実現できるようになりました。

画像2

ざっくり作る⑤ デザインを可愛くする

さて、一通りの画面遷移ができましたが圧倒的に見た目が可愛くないので次はボタンのデザインやフォントを可愛くしていこうと思います。

私の予想が正しければここらへんはCSSの領分なので「ボタン かわいい CSS」とかでググって出てきたやつを実装していきます。

フォントは第2回で考えていた「あんずもじ」にしていこうと思います。

CSSには@-規則 (At-rule)というものがあって、それを使えば以下のようにフォントファイルにパスを通して任意のフォントを使えるようです。

/* @-規則 */
/* 以下の例では AP.ttf というフォントファイルを ap というフォント名で使用する */
@font-face {
   font-family: ap;
   src: url(../fonts/AP.ttf);
}

ボタンはステッチのついた可愛いボタンを採用します。
選択肢と他のボタンが同じ色だと味気ないので選択肢だけ色を変えます。

style.css

/* 利用するフォントを追加 */
@font-face {
   font-family: ap;
   src: url(../fonts/AP.ttf);
}

body {
   margin-right: auto;
   margin-left : auto;
   text-align: center;
   height: 98vh;
   width: min(98vw, 1000px);
   padding: 0%;
}

div {
   margin: 0px;
}

label {
   font-family: ap; /* フォントファミリーを ap に設定 */
   font-size: min(10vw, 5vh);
   color: #644;
   display: block;
   text-align: center;
}

/* ボタンのデザインを追加 */
button {
   font-family: ap;
   font-size: min(7vw, 5vh);
   padding: 2%;
   margin: min(1.5vw, 15px);
   display: inline-block;
   color: #fff;
   border: #ffffff dashed 1px;
   box-shadow: 0 0 0 min(1vw, 10px) #996666;
   border-radius: min(1vw, 10px);
   background-color: #996666;
   cursor: pointer;
}
button:active {
   box-shadow: 0 0 0 min(1vw, 10px) #cc8888;
   background-color: #cc8888;
}

#message {
   margin-top:3%;
   height: 10%;
}
#image-area {
   text-align: center;
   height: 30%;
}
#button-area {
   margin-top: 3%;
   text-align: center;
   height: 30%;
   width: 100%;
}
#to-title-area {
   margin-top: 3%;
   height: 20%;
   text-align: center;
}

#image-area > Img {
   width: auto;
   height: 100%;
}

#options {
   height: 100%;
   margin-left:10%;
   margin-right:10%;
   display: grid;
   grid-template-rows: 50% 50%;
   grid-template-columns: 33% 34% 33%;
}

/* 選択肢領域のボタンだけは青くする */
#options > button {
   height:60%;
   font-size: min(5vw, 3vh);
   box-shadow: 0 0 0 min(1vw, 10px) #3355ff;
   background-color: #3355ff;
}
#options > button:active {
   box-shadow: 0 0 0 min(1vw, 10px) #5588ff;
   background-color: #5588ff;
}

#to-next {
   width: 50%;
   height: 30%;
}

#to-title {
   width: 50%;
   height: 50%;
}

ポイントは 「>」を使うことによってスタイルの適用範囲を制限できることですね。
上記のCSSでは #options > button とすることによって #options という id のdivタグ内にあるボタンだけ青くしています。

ブラウザで表示される画面

画像3

ボタンやフォントを変えるだけでかなり印象が変わりました!

まとめ

見た目も可愛くなってきました。

今は問題が常におんなじ問題で、表示される画像も常に同じ画像が表示されています。その上、正解しても正解しても終わらないアプリケーションになっているので次回は問題のバリエーションを増やしたり、画像をランダムで表示したりという部分を作っていきたいと思います。

それでは。


この記事が気に入ったらサポートをしてみませんか?