このページではソースコードの一部分を簡単な解説をしています。
完成品で遊ぶにはコチラから
完成品のソースコードはgithubにあります
並べ替えクイズ概要

ユーザーインターフェイスは上記写真のような感じにしたいと思います。1番上に問題文を表示し選択肢をクリックすると数字の書いてある所へ順番に移動し、すべて埋まると正解か判定します。
ユーザーインターフェイスをHTMLとCSSで作成

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
<title>並び替えクイズ</title>
</head>
<div id="game">
<h1>標高の高い順に並べ替えてください</h1>
<div id="field">
<div id="answer-area">
<div class="answer">1</div>
<div class="answer">2</div>
<div class="answer">3</div>
<div class="answer">4</div>
<div class="answer">5</div>
<div class="answer">6</div>
</div>
<div id="select-area">
<div class="select">金剛山</div>
<div class="select">北岳</div>
<div class="select">富士山</div>
<div class="select">高尾山</div>
<div class="select">奥穂高岳</div>
<div class="select">槍ヶ岳</div>
</div>
</div>
<div id="btn">
<button onclick="">リセット</button>
</div>
</div>
<script type="text/javascript" src="main.js"></script>
</body>
</html>body {
text-align: center;
user-select: none;
}
.answer {
display: inline-block;
padding: 0.5em 1em;
margin: 2em 0;
font-weight: bold;
color: #6091d3;/*文字色*/
background: #FFF;/*背景色*/
border: solid 3px #6091d3;/*線*/
border-radius: 10px;/*角の丸み*/
}
.select {
display: inline-block;
padding: 0.5em 1em;
margin: 2em 0;
font-weight: bold;
color: #6091d3;/*文字色*/
background: #FFF;/*背景色*/
border: solid 3px #6091d3;/*線*/
border-radius: 10px;/*角の丸み*/
}
.select:hover {
background: #333;/*背景色*/
border: 2px solid #333;
color: #fff;/*文字色*/
cursor: pointer;/*カーソルをポインターに変える*/
}
p {
padding: 0.5em 1em;
margin: 2em 0;
font-weight: bold;
color: #6091d3;/*文字色*/
}
#start:hover {
border: 2px solid #333;/*線*/
cursor: pointer;/*カーソルをポインターに変える*/
}JavaScriptを使って問題文と選択肢を挿入する
//問題
const question = [
{
q: "標高の高い順に並べ替えてください",
a: ["富士山", "北岳", "奥穂高岳", "槍ヶ岳", "金剛山", "高尾山"]
},
{
q: "標高の高い順に並べ替えてください",
a: ["エベレスト", "K2", "ダウラギリ", "マナスル", "ナンガパルバット", "アンナプルナ"]
},
{
q: "面積の大きい順に並べ替えてください",
a: ["琵琶湖", "霞ヶ浦", "サロマ湖", "猪苗代湖", "洞爺湖", "浜名湖"]
},
{
q: "面積の大きい順に並べ替えてください",
a: ["カスピ海", "スペリオル湖", "ビクトリア湖", "アラル海", "ミシガン湖", "バイカル湖"]
}
];問題文と答えの選択肢はオブジェクト型で作成し、配列に入っている選択肢はあとで正解か判定する時にも使うため左から正解順に並べています。
//選択肢を挿入する要素を取得
const select = document.querySelectorAll(".select");
//問題番号を管理
let questionnum = 0;
//問題の解答シャッフル Fisher–Yatesアルゴリズムを用いる
//値渡しコピーで配列に代入
let shufflea = question[questionnum].a.concat();
for (let i = shufflea.length - 1; i > 0; i--) {
let r = Math.floor(Math.random() * (i + 1));
let tmp = shufflea[i];
shufflea[i] = shufflea[r];
shufflea[r] = tmp;
}
//問題文挿入
document.querySelector("h1").textContent = question[questionnum].q;
//回答選択肢挿入
for (let i = 0; i < shufflea.length; i++) {
select[i].classList.remove('is-hidden');
select[i].textContent = shufflea[i];
}回答の選択肢が入っている配列は正解順に並んでいるのでFisher–Yatesアルゴリズムを用いてシャッフルをしconcatメソッドで配列を値渡しでコピーして新しい配列を作っています。ここまでのコードで回答の選択肢がブラウザを更新するたびにランダムに配置されるのを確認できると思います。
回答選択肢をクリックされたら回答欄に順番に移動し並べる
div.is-hidden {
display: none;
}
div.is-visible {
display: block;
}//移動先の要素を取得
const answer = document.querySelectorAll(".answer");
//クリックされた数をカウント
let count = 0;
//選択された答えを順番に格納
let answers = [];
//選択された答えを消す
for (let i = 0; i < shufflea.length; i++) {
select[i].onclick = () => {
select[i].classList.add('is-hidden');
//選択された答えを移動
answer[count].textContent = select[i].textContent;
answers.push(answer[count].textContent);
count += 1;
}
}クリックされた選択肢はCSSを使って消しています。
正解かどうかの判定
if (count == shufflea.length) {
if (JSON.stringify(question[questionnum].a) == JSON.stringify(answers)) {
document.querySelector("h1").innerHTML = "<p style=color:#f00;'>正解です!!</p>";
} else {
document.querySelector("h1").innerHTML = "<p style=color:#000;'>不正解...</p>";
}
}クリックされた数を格納している変数countが答えを格納している並列の要素数と同じになると判定の処理に移ります。JSON.stringifyメソッドを使い、一度JSON文字列に変換してから答えの配列を比較しています。
最後までお読みいただきありがとうございました。
完成品で遊ぶにはコチラから
完成品のソースコードはgithubにあります

