-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.js
341 lines (277 loc) · 12.1 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
//ローカル変数
let questionCount = 0;// 質問数をカウントする変数
let currentQuestion = null; // 現在出題されている問題を記録する変数
let selectedAnswer = ''; // ユーザーの選択を記録
let incorrectQuestions = [];// 間違えた問題を記録
let incorrectFlaggedQuestions = [];//Xだけフィルター
let correctAnswersCount = 0;// 正解した数をカウントする変数
let isFirstQuestion = true; // 判別するフラグ
// -----------------------------------------------------
// 外部JSONファイルを非同期で取得
function loadNextQuestion() {
fetch("questions.json")//ファイルをサーバーから取得
.then((response) => {
if (!response.ok) {
throw new Error("HTTPエラー: " + response.status);
}
return response.json();
})
.then((jsonData) => {
if (Array.isArray(jsonData)) {//配列かどうかを確認
const randomIndex = Math.floor(Math.random() * jsonData.length);
const question = jsonData[randomIndex];
displayQuestion(question);
//console.log("question:", question);// デバッグ
//console.log("jsonData:",jsonData);// デバッグ
} else {
console.error("jsonData は配列ではありません");
}
})
.catch((error) => {
console.error("次の質問の読み込みに失敗しました:", error);
});
}
// -----------------------------------------------------
// 質問を表示する処理
function displayQuestion(question) {
questionCount++; // 質問数をカウント
currentQuestion = question; // 現在の質問を記録
//console.log("question:", question);// デバッグ
//console.log("currentQuestion:", currentQuestion);// デバッグ
const contentDiv = document.getElementById("content");
contentDiv.innerHTML = `
<h5>問題番号: ${question.no} ${question.class1} ${question.class2}</h5>
<h2>第: ${questionCount}問目 正答数:${correctAnswersCount}/${questionCount}</h2>
<br>
<p>${question.text}</p>
<br>
<ul id="options"></ul>
<button id="submitButton" class="option-button" disabled>回答する</button>
`;
const optionsDiv = document.getElementById("options");
const optionLabels = ["A", "B", "C", "D"];
// 選択肢をシャッフルし、新しい正解のラベルを再設定
const { shuffledOptions, newAnswerLabel } = shuffleOptionsAndSetAnswer(
question.options,
question.answer
);
//console.log(`shuffledOptions${shuffledOptions}`);//デバッグ
//console.log(`newAnswerLabel${newAnswerLabel}`);//デバッグ
// ランダムに並び替えた選択肢にラベルを付与して表示
shuffledOptions.forEach((text, index) => {
const label = optionLabels[index]; // ラベルを再割り当て
const button = document.createElement("button");
button.textContent = `${label}`;
button.classList.add("option-button");
button.onclick = () => handleOptionClick(label);
const li = document.createElement("li");
li.textContent = `${label}. ${text}`;
optionsDiv.appendChild(li);
optionsDiv.appendChild(button);
});
// 回答ボタンのクリックイベント
document.getElementById("submitButton").onclick = () =>
handleSubmit(shuffledOptions, newAnswerLabel);
}
// -----------------------------------------------------
// 選択肢をシャッフルし、新しい正解のラベルを設定する関数
function shuffleOptionsAndSetAnswer(options, currentAnswerLabel) {
const optionLabels = ["A", "B", "C", "D"];
const correctOption = options[optionLabels.indexOf(currentAnswerLabel)]; // 現在の正答を取得
// 選択肢をシャッフル
const shuffledOptions = shuffleArray([...options]);
// 新しい正答のラベルを取得
const newAnswerIndex = shuffledOptions.indexOf(correctOption);
const newAnswerLabel = optionLabels[newAnswerIndex];
//console.log(`New: ${newAnswerLabel}`);// デバッグ
return { shuffledOptions, newAnswerLabel };
}
// -----------------------------------------------------
// 配列をランダムにシャッフルする関数
function shuffleArray(array) {
return array.sort(() => Math.random() - 0.5);
}
// -----------------------------------------------------
// 選択肢ボタンがクリックされたときの処理
function handleOptionClick(label) {
selectedAnswer = label; // ユーザーの選択を記録
const submitButton = document.getElementById("submitButton");
submitButton.disabled = false; // 回答ボタンを有効化
// 全ての選択肢ボタンのスタイルをリセット
const buttons = document.querySelectorAll(".option-button");
buttons.forEach((button) => {
button.style.backgroundColor = ""; // 背景色をリセット
button.style.color = ""; // テキスト色をリセット
button.style.border = ""; // ボーダーをリセット
});
// 選択したボタンのスタイルを変更
const selectedButton = Array.from(buttons).find(
(button) => button.textContent === label
);
if (selectedButton) {
selectedButton.style.backgroundColor = "lightblue"; // 背景色を設定
selectedButton.style.color = "white"; // テキスト色を変更
selectedButton.style.border = "2px solid blue"; // ボーダーを強調
}
//console.log(`選択: ${selectedAnswer}`);//デバッグ
}
// -----------------------------------------------------
// 回答が送信されたときの処理
function handleSubmit(shuffledOptions, newAnswerLabel) {
const resultModal = document.getElementById("resultModal");
const resultMessage = document.getElementById("resultMessage");
// 結果メッセージの設定
const message = selectedAnswer === newAnswerLabel
? `正解です!選択したのは "${selectedAnswer}"`
: `不正解です。正しい答えは "${newAnswerLabel}" でした。`;
resultMessage.textContent = message;
resultModal.style.display = "block";
// 正解/不正解の処理
const isCorrect = selectedAnswer === newAnswerLabel;
if (isCorrect) {
correctAnswersCount++;
removeIncorrectQuestion(currentQuestion.no); // 間違えた問題を削除
}
// 間違えた問題を記録
recordQuestion(isCorrect ? "〇" : "×");
// Local Storage に保存
saveIncorrectQuestionsToLocalStorage();
// 次の質問に進む
document.getElementById("nextQuestionButton").onclick = () => {
resultModal.style.display = "none";
proceedToNextQuestion();
};
}
// -----------------------------------------------------
// 間違えた問題を削除
function removeIncorrectQuestion(questionNo) {
const index = incorrectQuestions.findIndex((entry) => entry.no === questionNo);
if (index !== -1) {
incorrectQuestions.splice(index, 1); // 該当の問題を削除
}
}
// -----------------------------------------------------
// 問題を記録
function recordQuestion(flag) {
incorrectQuestions.push({
date: new Date().toLocaleDateString(),
flag: flag,
no: currentQuestion.no,
class1: currentQuestion.class1,
class2: currentQuestion.class2,
text: currentQuestion.text,
options: currentQuestion.options,
answer: currentQuestion.answer,
});
}
// -----------------------------------------------------
// 次の質問に進む
function proceedToNextQuestion() {
if (isFirstQuestion) {
loadNextQuestion(); // 初回の場合は通常の質問を表示
} else {
if (incorrectFlaggedQuestions.length === 0) {
alert("間違えた問題が無くなりました 全問から出題します。");
isFirstQuestion = true; // フラグを変更
loadNextQuestion(); // 通常の質問を表示
} else {
const randomIndex = Math.floor(Math.random() * incorrectQuestions.length);
displayQuestion(incorrectFlaggedQuestions[randomIndex]); // ランダムな問題を選択して表示
}
}
}
// -----------------------------------------------------
// ページ表示や間違えた問題の一覧表示時に Local Storage からデータを使用
function createIncorrectQuestionsTable() {
const incorrectQuestionsList = document.getElementById("incorrectQuestionsList");
incorrectQuestionsList.innerHTML = ""; // リストをクリア
// テーブルのヘッダーを作成
incorrectQuestionsList.innerHTML = `
<table border="1">
<thead>
<tr>
<th>回答日</th>
<th>正答</th>
<th>問題番号</th>
<th>大分類</th>
<th>中分類</th>
<th>質問内容</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
`;
const tableBody = incorrectQuestionsList.querySelector("tbody");
// 間違えた問題をテーブルに追加
incorrectQuestions.forEach((entry) => {
const tr = document.createElement("tr");
tr.innerHTML = `
<td>${entry.date}</td>
<td>${entry.flag}</td>
<td>${entry.no}</td>
<td>${entry.class1}</td>
<td>${entry.class2}</td>
<td>${entry.text}</td>
`;
tableBody.appendChild(tr);
});
}
// -----------------------------------------------------
// ページ表示や間違えた問題の一覧表示時に Local Storage からデータを使用
function showIncorrectQuestions() {
loadIncorrectQuestionsFromLocalStorage(); // 最新のデータをロード
// 間違えた問題のテーブル作成
createIncorrectQuestionsTable();
// 現在のページを非表示にして、間違えた問題一覧ページを表示
document.getElementById("content").style.display = "none";
document.getElementById("incorrectQuestionsPage").style.display = "block";
document.getElementById("showIncorrect").style.display = "none";
}
// -----------------------------------------------------
// 間違えた問題だけの出題ページ
function IncorrectAllQuestions() {
if (incorrectQuestions.length === 0) {
console.log("間違えた問題がありません。");
alert("間違えた問題がありません。");
return;
}
correctAnswersCount = 0;
questionCount = 0;
document.getElementById("incorrectQuestionsPage").style.display = "none";
document.getElementById("content").style.display = "block";
//document.getElementById("incorrectQuestionsList").innerHTML = ""; // リストをクリア
document.getElementById("showIncorrect").style.display = "block";//再表示
// '×' のフラグを持つ問題のみをフィルタリング
const incorrectFlaggedQuestions = incorrectQuestions.filter(question => question.flag === "×");
// ランダムなインデックスを生成(incorrectFlaggedQuestions.length を使用)
const randomIndex = Math.floor(Math.random() * incorrectFlaggedQuestions.length);
displayQuestion(incorrectFlaggedQuestions[randomIndex]); // ランダムな問題を選択して表示
isFirstQuestion = false; // フラグを変更
}
// -----------------------------------------------------
// Local Storage に保存
function saveIncorrectQuestionsToLocalStorage() {
localStorage.setItem("incorrectQuestions", JSON.stringify(incorrectQuestions));
}
// -----------------------------------------------------
// Local Storage から読み込み
function loadIncorrectQuestionsFromLocalStorage() {
const storedData = localStorage.getItem("incorrectQuestions");
if (storedData) {
incorrectQuestions = JSON.parse(storedData);
} else {
incorrectQuestions = []; // データが無い場合は空の配列
}
}
// ページ読み込み時に Local Storage からデータをロード
loadIncorrectQuestionsFromLocalStorage();
// -----------------------------------------------------
function clearLocalStorage() {
localStorage.clear();
//console.log("Local Storage をすべてクリアしました!");
incorrectQuestionsList.innerHTML = "";
}
// -----------------------------------------------------
// 初期状態で質問を表示 js呼び出し後にloadNextQuestionを起動
loadNextQuestion();