以下はJavaScriptを使用した、お題を指定されるとそれに関するクイズを出すアプリの実装例です。セキュリティ脆弱性に関する検討を行った上で実装してください。
```html
<!DOCTYPE html>
<html>
<head>
<title>クイズアプリ</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
body {
font-family: "Arial", sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
text-align: center;
}
h1 {
margin-top: 20px;
}
form {
margin-top: 20px;
}
label {
display: block;
margin-bottom: 10px;
}
input[type="text"] {
border: 2px solid #ccc;
border-radius: 5px;
padding: 5px;
width: 50%;
}
button {
background-color: #4CAF50;
border: none;
border-radius: 5px;
color: white;
padding: 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin-top: 10px;
cursor: pointer;
}
#quiz {
display: none;
margin-top: 20px;
}
#question {
font-size: 24px;
margin-bottom: 10px;
}
#answers {
margin-top: 10px;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.answer {
background-color: #fff;
border: 2px solid #ccc;
border-radius: 5px;
color: #333;
cursor: pointer;
font-size: 16px;
margin-right: 10px;
margin-bottom: 10px;
padding: 10px;
text-align: center;
min-width: 150px;
transition: all 0.2s ease;
}
.answer:hover {
background-color: #333;
color: #fff;
}
.correct {
background-color: #4CAF50;
color: #fff;
border-color: #4CAF50;
}
.incorrect {
background-color: #f44336;
color: #fff;
border-color: #f44336;
}
#score {
font-size: 24px;
margin-top: 20px;
}
#restart {
background-color: #4CAF50;
border: none;
border-radius: 5px;
color: white;
padding: 10px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin-top: 20px;
cursor: pointer;
}
</style>
</head>
<body>
<h1>クイズアプリ</h1>
<form>
<label for="topic">お題を入力してください:</label>
<input type="text" id="topic" name="topic" required>
<button type="submit">スタート</button>
</form>
<div id="quiz">
<p id="question"></p>
<div id="answers"></div>
<p id="score"></p>
<button id="restart">もう一度プレイする</button>
</div>
<script type="text/javascript">
const quizData = {
"JavaScript": [
{
"question": "JavaとJavaScriptは同じものですか?",
"answers": [
{ "text": "はい", "correct": false },
{ "text": "いいえ", "correct": true }
]
},
{
"question": "JavaScriptでウェブページの要素を取得するための命令は次のうちどれですか?",
"answers": [
{ "text": "getElementById", "correct": true },
{ "text": "getElementsByTag", "correct": false },
{ "text": "getElementByClass", "correct": false },
{ "text": "getElementByName", "correct": false }
]
},
{
"question": "JavaScriptのクロージャは何ですか?",
"answers": [
{ "text": "単一の関数によって生成され、変数のスコープを維持する関数", "correct": true },
{ "text": "JavaScriptのフレームワーク", "correct": false },
{ "text": "JavaScriptで繰り返し処理を実行するための命令", "correct": false },
{ "text": "JavaScriptで文字列を検索するための命令", "correct": false }
]
}
],
"HTML": [
{
"question": "HTMLの略称は何ですか?",
"answers": [
{ "text": "Hyper Tech Markup Language", "correct": false },
{ "text": "Hyper Text Markup Language", "correct": true },
{ "text": "High Tech Markup Language", "correct": false },
{ "text": "High Text Markup Language", "correct": false }
]
},
{
"question": "HTMLで文字を強調するタグは何ですか?",
"answers": [
{ "text": "<em>", "correct": true },
{ "text": "<strong>", "correct": false },
{ "text": "<italic>", "correct": false },
{ "text": "<underline>", "correct": false }
]
},
{
"question": "HTMLで画像を挿入するタグは何ですか?",
"answers": [
{ "text": "<img>", "correct": true },
{ "text": "<link>", "correct": false },
{ "text": "<a>", "correct": false },
{ "text": "<div>", "correct": false }
]
}
],
"CSS": [
{
"question": "CSSの略称は何ですか?",
"answers": [
{ "text": "Computer Style Sheets", "correct": false },
{ "text": "Cascading Style Sheets", "correct": true },
{ "text": "Crazy Style Sheets", "correct": false },
{ "text": "Classic Style Sheets", "correct": false }
]
},
{
"question": "CSSで文字色を変える命令は次のうちどれですか?",
"answers": [
{ "text": "color", "correct": true },
{ "text": "background-color", "correct": false },
{ "text": "font-family", "correct": false },
{ "text": "text-align", "correct": false }
]
},
{
"question": "CSSでボタンに影を付けるにはどうすればよいですか?",
"answers": [
{ "text": "shadow", "correct": false },
{ "text": "box-shadow", "correct": true },
{ "text": "text-shadow", "correct": false },
{ "text": "border-shadow", "correct": false }
]
}
]
};
const quizContainer = document.getElementById("quiz");
const questionEl = document.getElementById("question");
const answerButtonsEl = document.getElementById("answers");
const scoreEl = document.getElementById("score");
const restartButton = document.getElementById("restart");
let currentTopic;
let shuffledQuestions;
let currentQuestionIndex;
let score = 0;
restartButton.addEventListener("click", startGame);
function startGame(event) {
event.preventDefault();
const topic = document.getElementById("topic").value.trim();
if (quizData.hasOwnProperty(topic)) {
currentTopic = topic;
currentQuestionIndex = 0;
score = 0;
scoreEl.textContent = "";
scoreEl.style.display = "none";
restartButton.style.display = "none";
quizContainer.style.display = "block";
shuffledQuestions = shuffleArray(quizData[currentTopic]);
setNextQuestion();
}
else {
alert("指定されたお題はありません。別のお題を入力してください。");
}
}
function setNextQuestion() {
resetState();
showQuestion(shuffledQuestions[currentQuestionIndex]);
}
function showQuestion(question) {
questionEl.textContent = question.question;
question.answers.forEach(answer => {
const button = document.createElement("button");
button.textContent = answer.text;
button.classList.add("answer");
if (answer.correct) {
button.dataset.correct = answer.correct;
}
button.addEventListener("click", selectAnswer);
answerButtonsEl.appendChild(button);
});
}
function resetState() {
while (answerButtonsEl.firstChild) {
answerButtonsEl.removeChild(answerButtonsEl.firstChild);
}
}
function selectAnswer(event) {
const selectedButton = event.target;
const correct = selectedButton.dataset.correct;
if (correct) {
selectedButton.classList.add("correct");
score++;
}
else {
selectedButton.classList.add("incorrect");
}
Array.from(answerButtonsEl.children).forEach(button => {
if (button.dataset.correct) {
button.classList.add("correct");
}
});
if (currentQuestionIndex < shuffledQuestions.length - 1) {
currentQuestionIndex++;
setTimeout(setNextQuestion, 1000);
}
else {
scoreEl.textContent = `あなたのスコアは${score}/${shuffledQuestions.length}でした!`;
scoreEl.style.display = "block";
restartButton.style.display = "block";
}
}
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
</script>
</body>
</html>
```
注意:このアプリはセキュリティに関する検討が不十分なため、実際のアプリケーションとしては使用しないでください。セキュリティリスクについては、定期的にチェックを行い、改善するようにしてください。また、このアプリは教育目的のための例示のため、開発者は一切の責任を負いかねます。