-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathquiz.html
More file actions
358 lines (347 loc) · 16.2 KB
/
Copy pathquiz.html
File metadata and controls
358 lines (347 loc) · 16.2 KB
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
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ôn thi trắc nghiệm</title>
<style>
*{font-size:14px;font-family:arial}body{margin:auto}button{background-color:aqua;margin:4px}.btn{min-height:16px;min-width:16px}.select{min-height:30px;min-width:150px;margin-right:10px}.selectoption{display:flex}.btn2{display:inline-flex;flex-direction:row;align-items:center;border:none;border-radius:3px;cursor:pointer;font-size:14px;justify-content:center;padding:5px 10px;text-align:left;vertical-align:middle;min-height:30px;min-width:40px}.container{background-color:rgb(111 90 193);color:rgb(255,255,255);transition:box-shadow 300ms cubic-bezier(.4,0,.2,1) 0ms;background-image:none;margin-left:auto;margin-right:auto;width:100%;padding:10px;max-width:480px;border-radius:10px;box-shadow:rgba(0,0,0,.24) 0 8px 16px 0;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.left-box{padding:8px}.right-box{padding:8px;display:flex;justify-content:space-between}.btn{margin:10px;padding:4px;cursor:pointer}.bold{font-weight:600}.quiz{margin:auto}.popup{position:fixed;height:100vh;width:70%;left:10%;margin:auto;z-index:2;box-shadow:rgba(0,0,0,.33) -3px 2px 10px 1px;color:rgb(92,92,92);transform:translate(60px);border-radius:12px;transition:all 0.2s ease-out 0s;background:rgb(255,255,255);overflow:auto}.left{float:left;font-size:20px}.popup_content{padding:0 8px 0 8px;margin:15px 8px}.popup_footer{position:fixed;right:10px}h1{font-size:16px}::-webkit-scrollbar{width:7px;height:7px;background:transparent}.top{top:0;padding:8px;font-size:20px;font-weight:700;background-image:linear-gradient(90deg,#3F51B5 0%,#0770C0 100%);color:rgb(255,255,255);height:20px}.right{position:absolute;top:0;margin-left:10px;border:solid aqua 1px;padding:4px;border-radius:4px}#clock-container{font-size:20px;color:red;margin-right:20px}.answer{display:none;margin:4px}.fileupload{display:none}.update,.download,.import{cursor:pointer;color:#fff;margin:4px}.tool{margin:4px}::-webkit-scrollbar-thumb{background:rgb(204,204,204);border-radius:10px}::-webkit-scrollbar-track{box-shadow:grey 0 0 0 inset;border-radius:1px}
</style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<style id="option"></style>
<div class="container">
<div class="left-box">
<div class="bold" style="margin-bottom:8px;font-size:16px;"> Chọn bộ đề : </div>
<div class="selectoption">
<select id="selectsource" class="select"></select>
<select id="mySelect" class="select"></select>
</div>
<button class="btn2 btn-primary" id="btn-start">Ôn tập</button>
<button class="btn2 btn-primary" id="btn-check">Kiểm tra</button>
</div>
<div class="right-box">
<div>
<div class="bold"> Tuỳ chọn đề thi</div>
<li>Số câu hỏi : <input type="number" id="numberq" min="50" max="200" step="5" value="50" /><br/></li>
<li> Thời gian làm : <input type="number" id="timer" min="10" max="60" step="1" value="30"/><br/></li>
</div>
<button class="btn2 btn-primary" id="btn-test" style="text-align:center;">Thi thử <br/>(Đề ngẫu nhiên)</button>
<img src="src/img/128.png" style="width:60px; height: 60px;"/>
</div>
</div>
<div class="right clock-container" id="clock-container"><img src="./src/clock.png" style="height:20px; width:20px;"/> 07:00</div>
<div class="quiz" id="mainquiz"></div>
<script src="https://raw.githubusercontent.com/drphe/data/main/data.js"></script>
<script type="text/javascript">
// ---Khởi tạo
const CONFIG = {
localStorageID: "answer",
timer: 30, // thời gian bài thi
numberquestion: 30, // số câu hỏi trong bài test
numberquestiontest: 50, // số câu hỏi trong bài thi
};
var countdownInterval;
const optionData = {},
resetAll();
//---- thao tác nguồn dữ liệu
// lấy danh sách nguồn
for (const key in DATA) optionData[key] = DATA[key].name;
const optionsource = Object.entries(optionData).map(([key, value]) => `<option value="${key}">${key}</option>`);
const selectsource = document.getElementById("selectsource");
const select = document.getElementById("mySelect");
selectsource.innerHTML = optionsource.join("");
getModule();
// lấy ds module
function getModule() {
const selectedOption = selectsource.options[selectsource.selectedIndex];
try{
const value = selectedOption.value;
let odata = {};
for (const key in DATA[value]) {
odata[key] = DATA[value][key].name;
}
const options = Object.entries(odata).map(([key, value]) => `<option value="${key}">${value}</option>`);
select.innerHTML = options.join("");
}catch(e){}
}
// lấy dữ liệu
function getModuleData(full = false) {
CONFIG.numberquestiontest = document.getElementById("numberq").value;
CONFIG.timer = document.getElementById("timer").value;
const selectedOption1 = selectsource.options[selectsource.selectedIndex];
const selectedOption2 = select.options[select.selectedIndex];
const e = selectedOption1.value,
t = selectedOption2.value;
var source = {};
if (full) {
var j = 1;
source.name = e;
for (const k in DATA[e]) {
for (const [key, value] of Object.entries(DATA[e][k])) {
if(key !== "name"){
source[j.toString()] = value;
j++;
}
}
}
} else {
source = Object.assign({}, DATA[e][t]);
}
return source;
}
// ----kiểm tra nút bấm
// thay đổi nguồn dữ liệu
document.getElementById("selectsource").addEventListener("change", () => {
getModule();
});
// ôn tập
document.getElementById("btn-start").addEventListener("click", () => {
const source = getModuleData()
showPopup(source)
});
// kiểm tra
document.getElementById("btn-check").addEventListener("click", () => {
const source = getModuleData()
showPopup(source, 2)
});
// thi thử
document.getElementById("btn-test").addEventListener("click", () => {
const source = getModuleData(true)
showPopup(source, 3)
});
//-----Phần tạo popup câu hỏi, chấm thi
function showPopup(source, loai = 1) {
// khai báo
var name = source.name,
popuptitle = '',
chamthi = '';
let mainquiz = document.getElementById("mainquiz");
mainquiz.innerHTML = '';
try {
delete source.name;
} catch (e) {}
let count = 0;
for (const key in source) count++;
switch (loai) {
case 1: // ôn tập
addAnswerStyle();
popuptitle = `Ôn tập ${name}: ${count} câu`;
chamthi = `<button type="button" class="btn2 checkA"><span>Test</span></button>`;
break;
case 2: // kiểm tra
counter();
chamthi = `<button type="button" class="btn2 checkA"><span>Kiểm tra</span></button>`;
popuptitle = `Kiểm tra ${name}: ${CONFIG.numberquestion} câu`;
break;
case 3:
counter();
chamthi = ` <button type="button" class="btn2 checkA"><span>Nộp bài</span></button>`;
popuptitle = `Thi thử ${name}: ${CONFIG.numberquestiontest}/${count} câu`;
break;
default:
}
// tạo popup
let popup = document.createElement("div");
popup.classList.add("popup");
popup.innerHTML = `<div class="top" id="topcontainer"><div class="left" id="title">${popuptitle}</div></div>
<div class="popup_content"><h1>Bài thi trắc nghiệm</h1>${cTest(source, loai)}</div>`;
popup.innerHTML += `<div class="popup_footer">${chamthi}<button type="button" class="btn2 close"><span>× Đóng</span></button></div>`;
mainquiz.appendChild(popup);
// check answers
var answers = {};
document.addEventListener("click", (event) => {
if (event.target.tagName === "INPUT" && event.target.type === "radio" && event.target.id) {
const answer = event.target.value;
const key = event.target.name.split("-")[1];
let mainquiz = document.getElementById("mainquiz");
let button = mainquiz.querySelectorAll('.btn-' + key);
button.forEach(btn => {
btn.classList.remove('correct');
btn.classList.remove('wrong');
});
// check kết quả
const DA = ["A", "B", "C", "D", "E", "F"];
let answerQ = DA[answer-1];
let btntext = mainquiz.querySelector('.' + event.target.id)
let keytext = mainquiz.querySelector('.key-' + key);
if (answerQ == source[key].A) {
btntext.classList.add('correct');
keytext.innerHTML = "Đáp án Đúng!"
} else {
btntext.classList.add('wrong');
keytext.innerHTML = "Đáp án bạn chọn không đúng, đáp án đúng là " + source[key].A;
}
// lưu kết quả
let t = JSON.parse(localStorage.getItem(CONFIG.localStorageID));
let answers = null === t ? [] : t;
let index = -1
try {
index = answers.findIndex(s => s.q === key)
} catch (e) {}
if (index === -1) {
answers.push({
q: key,
a: answerQ,
s: answerQ == source[key].A ? 1 : 0
})
} else {
answers[index].a = answerQ
answers[index].s = answerQ == source[key].A ? 1 : 0
}
localStorage.setItem(CONFIG.localStorageID, JSON.stringify(answers));
//console.log(answers);
}
});
// nút bấm trong popup
popup.querySelector(".close").addEventListener("click", () => {
popup.remove(); // đóng
resetAll();
});
popup.querySelector(".checkA").addEventListener("click", () => {
if (loai == 1) {
resetAll(false);
source.name = name;
showPopup(source, 2);
} else {
checkAnswer(); // chấm thi
}
});
}
//tạo bài test
function cTest(data, loai = 1) {
let temp = "";
let key = Object.keys(data);
switch (loai) {
case 1: // tất cả
key.forEach(s => {
temp += cQuestion(s, data[s]);
});
break;
case 2: // ngẫu nhiên
const rand = shuffle(getRandomSubarray(key, CONFIG.numberquestion));
let i = 1; // số câu hỏi
rand.forEach(s => {
temp += cQuestion(s, data[s], i);
i++;
});
break;
case 3: // thi thử
const randt = shuffle(getRandomSubarray(key, CONFIG.numberquestiontest));
let j = 1; // số câu hỏi
randt.forEach(s => {
temp += cQuestion(s, data[s], j);
j++;
});
break;
default:
}
return temp;
}
// tạo câu hỏi
function cQuestion(key, data, index = 0) {
const DA = ["A", "B", "C", "D", "E", "F"];
function inputhtml(i) {
return data.hasOwnProperty(i) ? `<input type="radio" name = "btn-${key}" class="btn" id="btn-${key}-${i}" value="${i}"/><span class="btn-${key} btn-${key}-${i}"> ${DA[i-1]}.${data[i]}</span> <br/>` : "";
}
for (var input = "", j = 1; j < 6; j++) input += inputhtml(j);
return `<form><h2 id="${key}">Câu hỏi ${index? index: key}: ${data.Q}</h2>${input}<div class="answer key-${key}"></div> </form>`
}
// tạo bộ đề ngẫu nhiên
function getRandomSubarray(arr, size) {
var shuffled = arr.slice(0);
var i = arr.length;
var temp, index;
while (i--) {
index = Math.floor(Math.random() * (i + 1));
temp = shuffled[index];
shuffled[index] = shuffled[i];
shuffled[i] = temp;
}
return shuffled.slice(0, size);
}
function shuffle(array) {
let currentIndex = array.length,
randomIndex;
// Trong khi vẫn còn phần tử để sắp xếp lộn xộn
while (currentIndex > 0) {
// Chọn một phần tử ngẫu nhiên
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// Và hoán đổi nó với phần tử hiện tại
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]
];
}
return array;
}
// bộ đếm giờ
function counter() {
clearInterval(countdownInterval);
let divclock = document.querySelector(".clock-container");
let countdownTime = CONFIG.timer * 60;
countdownInterval = setInterval(function() {
// Calculate minutes and seconds
let minutes = Math.floor(countdownTime / 60);
let seconds = countdownTime % 60;
divclock.innerHTML = `<img src="./src/clock.jpg" style="height:20px; width:20px;"/> ${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
if (countdownTime === 0) {
clearInterval(countdownInterval);
checkAnswer();
} else {
// Decrease the countdown time
countdownTime--;
}
}, 1000); // Update every second
};
// đồng hồ
function clock() {
countdownInterval = setInterval(() => {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
document.querySelector(".clock-container").innerHTML = `<img src="./src/clock.png" style="height:20px; width:20px;"/> ` + hour.toString().padStart(2, '0') + ":" + minute.toString().padStart(2, '0');
}, 1000);
}
// chấm thi
function checkAnswer() {
let mainquiz = document.getElementById("mainquiz");
for (const radio of mainquiz.querySelectorAll("input[type='radio']")) radio.disabled = true;
addAnswerStyle();
clearInterval(countdownInterval);
let t = JSON.parse(localStorage.getItem(CONFIG.localStorageID));
let answers = null === t ? [] : t;
let total = answers.length // tổng câu hỏi
const sum = answers.reduce((acc, item) => {
return acc + item.s;
}, 0); // tổng điểm
result(sum + '/' + total);
}
// hiển thị kết quả chấm bài
function result(x) {
let div = document.createElement("div");
div.id = "result";
div.setAttribute("style", "max-width: 60%; min-width: 150px; padding: 0px 14px; color: rgb(255, 255, 255); line-height: 40px; text-align: center; border-radius: 4px; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 999999; background: rgba(0, 0, 0, 0.7); font-size: 16px; transition: transform 0.5s ease-in 0s, opacity 0.5s ease-in 0s; opacity: 1;");
div.innerHTML = ` Điểm số của bạn là: ${x} <br/>
<button type="button" class="btn2 close-result">
<span>× Đóng</span>
</button>`;
document.body.appendChild(div);
div.querySelector(".close-result").addEventListener("click", () => {
div.remove();
});
}
// reset
async function resetAll(quiz = true) {
const result = document.querySelector("#result");
if (result) {
document.body.removeChild(result);
}
clearInterval(countdownInterval);
await localStorage.setItem(CONFIG.localStorageID, JSON.stringify([]));
quiz && (document.getElementById("mainquiz").innerHTML = "", await clock());
document.getElementById("option").innerHTML = "";
}
</script>
</body>
</html>