This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@charset "utf-8"; | |
:root{ | |
--main-color: #0288D1; | |
--sub-color: #B3E5FC; | |
--attention-color: #D32F2F; | |
--correct-color: #D32F2F; | |
--wrong-color: #303F9F; | |
} | |
#quiz{ | |
width: 100%; | |
max-width: 600px; | |
height: 100%; | |
max-height: 95vh; | |
position: fixed; | |
top: 50%; | |
left: 50%; | |
z-index: 500; | |
transform: translate(-50%,-50%); | |
border-radius: 8px; | |
background-color: #fff; | |
box-shadow: 0 0 5px 5px rgba(60,60,60,.2); | |
} | |
/* */ | |
#quiz__area-n{ | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
height: 10%; | |
} | |
/* */ | |
#quiz__area-q{ | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
box-sizing: border-box; | |
height: 35%; | |
padding: 16px; | |
overflow-y: auto; | |
color: var(--main-color); | |
font-size: 30px; | |
line-height: 1.5em; | |
} | |
/* */ | |
#quiz__area-a{ | |
height: 45%; | |
overflow-y: auto; | |
background-color: var(--sub-color); | |
user-select: none; | |
} | |
.unit-a__answer{ | |
margin: 16px; | |
} | |
.answer__radio{ | |
display: none; | |
} | |
.answer__label{ | |
display: block; | |
box-sizing: border-box; | |
padding: 4px; | |
background-color: #fff; | |
text-align: center; | |
cursor: pointer; | |
} | |
.answer__radio:checked+.answer__label{ | |
background-color: var(--main-color); | |
color: #fff; | |
} | |
.bt-end{ | |
display: block; | |
box-sizing: border-box; | |
width: 100%; | |
padding: 4px; | |
border: none; | |
background-color: #fff; | |
text-align: center; | |
cursor: pointer; | |
} | |
/* */ | |
.quiz__area-c{ | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
height: 10%; | |
user-select: none; | |
} | |
.bt-control{ | |
padding: 2px 8px; | |
margin: 0 16px; | |
border: 1px solid var(--main-color); | |
background-color: #fff; | |
cursor: pointer; | |
} | |
#bt-confirm{ | |
border: none; | |
background-color: var(--attention-color); | |
color: #fff; | |
} | |
/* */ | |
.quiz-res__table{ | |
margin: 0 auto; | |
border-collapse: collapse; | |
} | |
.quiz-res__head__td{ | |
box-sizing: border-box; | |
padding: 8px 16px; | |
border: 1px solid var(--main-color); | |
background-color: var(--sub-color); | |
text-align: center; | |
color: var(--main-color); | |
} | |
.quiz-res__td{ | |
box-sizing: border-box; | |
padding: 8px 16px; | |
border: 1px solid var(--main-color); | |
} | |
.quiz-res__td-a__inner{ | |
display: flex; | |
align-items: center; | |
} | |
.quiz-res__mark{ | |
display: inline-flex; | |
justify-content: center; | |
align-items: center; | |
width: 20px; | |
margin-right: 16px; | |
} | |
.quiz-res__maru{ | |
color: var(--correct-color); | |
} | |
.quiz-res__correct{ | |
color: var(--correct-color); | |
} | |
.quiz-res__batsu{ | |
color: var(--wrong-color); | |
} | |
.quiz-res__wrong{ | |
text-decoration: line-through; | |
color: var(--wrong-color); | |
} | |
.quiz-res__td-sum{ | |
text-align: right; | |
} | |
/* */ | |
.s-hide{ | |
display: none; | |
} | |
.s-invisible{ | |
visibility: hidden; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* quiz-maker.js v1.0 | |
* | |
* Copyright (c) 2022 motsu | |
* | |
* Released under the MIT license. | |
* see https://opensource.org/licenses/MIT | |
*/ | |
class quizMaker{ | |
#json; | |
#num_quiz = 0; | |
#len_quiz; | |
#body = document.getElementById('quiz'); | |
constructor(src){ | |
this.url_json = src; | |
this.#loadJson(); | |
} | |
#loadJson(){ | |
fetch(this.url_json,{ | |
method: 'GET' | |
}).then(response=>{ | |
if(response.ok){ | |
//通信成功 | |
return response.json(); | |
}else{ | |
//通信失敗 | |
this.#dispError(); | |
} | |
}).then(json=>{ | |
this.#json = json; | |
this.#len_quiz = this.#json.length; | |
this.#makeQuiz(); | |
this.#body.classList.remove('hide'); | |
}) | |
.catch(error=>{ | |
this.#dispError(); | |
}); | |
} | |
#dispError(){ | |
document.getElementById('quiz-res').textContent = 'クイズデータの取得に失敗しました。'; | |
} | |
#makeQuiz(){ | |
const el_area_q = document.getElementById('quiz__area-q'); | |
const el_area_a = document.getElementById('quiz__area-a'); | |
this.#json.forEach((data,i)=>{ | |
//問題欄 | |
const el_unit_q = document.createElement('div'); | |
el_unit_q.classList.add('area-q__unit-q'); | |
if(i!=0) el_unit_q.classList.add('s-hide'); | |
el_unit_q.innerHTML = escHtml(data['question']).replace(/\n/g,'<br>'); | |
el_area_q.appendChild(el_unit_q); | |
//回答欄 | |
const el_unit_a = document.createElement('div'); | |
el_unit_a.classList.add('area-a__unit-a'); | |
if(i!=0) el_unit_a.classList.add('s-hide'); | |
el_area_a.appendChild(el_unit_a); | |
data['answers'].forEach((a,j)=>{ | |
const el_answer = document.createElement('div'); | |
el_answer.classList.add('unit-a__answer'); | |
el_unit_a.appendChild(el_answer); | |
const el_radio_answer = document.createElement('input'); | |
el_radio_answer.type = 'radio'; | |
el_radio_answer.name = 'radio'+i; | |
el_radio_answer.id = `radio${i}-${j}`; | |
el_radio_answer.value = j; | |
el_radio_answer.classList.add('answer__radio'); | |
el_answer.appendChild(el_radio_answer); | |
const el_label_answer = document.createElement('label'); | |
el_label_answer.htmlFor = el_radio_answer.id; | |
el_label_answer.classList.add('answer__label') | |
el_label_answer.textContent = a; | |
el_answer.appendChild(el_label_answer); | |
}); | |
}); | |
//confirm最後尾へ | |
const el_confirm_q = document.getElementById('confirm-q'); | |
const el_confirm_a = document.getElementById('confirm-a'); | |
el_area_q.appendChild(el_confirm_q); | |
el_area_a.appendChild(el_confirm_a); | |
//リスナ設定 | |
const el_area_n = document.getElementById('quiz__area-n'); | |
const els_unit_q = document.getElementsByClassName('area-q__unit-q'); | |
const els_unit_a = document.getElementsByClassName('area-a__unit-a'); | |
const bt_prev = document.getElementById('bt-prev'); | |
const bt_confirm = document.getElementById('bt-confirm'); | |
const bt_next = document.getElementById('bt-next'); | |
const bt_end_no = document.getElementById('bt-end-no'); | |
const bt_end_yes = document.getElementById('bt-end-yes'); | |
bt_prev.addEventListener('click',()=>{ | |
changeQuestion(this,-1); | |
}); | |
bt_next.addEventListener('click',()=>{ | |
changeQuestion(this,1); | |
}); | |
bt_confirm.addEventListener('click',()=>{ | |
confirm(this); | |
}); | |
bt_end_no.addEventListener('click',e=>{ | |
e.preventDefault(); | |
confirmNo(this); | |
}) | |
bt_end_yes.addEventListener('click',e=>{ | |
e.preventDefault(); | |
confirmYes(this); | |
}) | |
writeNumber(this); | |
function changeQuestion(QM,diff){ | |
QM.#num_quiz += diff; | |
if(QM.#num_quiz<0) QM.#num_quiz = 0; | |
if(QM.#num_quiz>QM.#len_quiz-1) QM.#num_quiz = QM.#len_quiz - 1; | |
if(QM.#num_quiz==0){ | |
bt_prev.classList.add('s-invisible'); | |
}else{ | |
bt_prev.classList.remove('s-invisible'); | |
} | |
if(QM.#num_quiz==QM.#len_quiz-1){ | |
bt_next.classList.add('s-invisible'); | |
}else{ | |
bt_next.classList.remove('s-invisible'); | |
} | |
for(let i=0;i<QM.#len_quiz;i++){ | |
if(i==QM.#num_quiz){ | |
els_unit_q[i].classList.remove('s-hide'); | |
els_unit_a[i].classList.remove('s-hide'); | |
}else{ | |
els_unit_q[i].classList.add('s-hide'); | |
els_unit_a[i].classList.add('s-hide'); | |
} | |
} | |
writeNumber(QM); | |
} | |
function writeNumber(QM) { | |
el_area_n.textContent = `問 ${QM.#num_quiz+1}/${QM.#len_quiz}`; | |
} | |
function confirm(QM){ | |
els_unit_q[QM.#num_quiz].classList.add('s-hide'); | |
els_unit_a[QM.#num_quiz].classList.add('s-hide'); | |
bt_prev.classList.add('s-invisible'); | |
bt_next.classList.add('s-invisible'); | |
bt_confirm.classList.add('s-invisible'); | |
el_confirm_q.classList.remove('s-hide'); | |
el_confirm_a.classList.remove('s-hide'); | |
} | |
function confirmNo(QM){ | |
el_confirm_q.classList.add('s-hide'); | |
el_confirm_a.classList.add('s-hide'); | |
bt_confirm.classList.remove('s-invisible'); | |
changeQuestion(QM,0); | |
} | |
function confirmYes(QM){ | |
//採点中表示 | |
bt_end_yes.classList.add('s-invisible') | |
bt_end_no.classList.add('s-invisible'); | |
//要素準備 | |
const el_res = document.getElementById('quiz-res'); | |
el_res.textContent = ''; | |
const el_table_res = document.createElement('table'); | |
el_table_res.classList.add('quiz-res__table'); | |
const el_form = el_area_a; | |
//見出し | |
const el_table__head = document.createElement('tr'); | |
const el_table__head__td_q = document.createElement('td'); | |
el_table__head__td_q.classList.add('quiz-res__head__td'); | |
el_table__head__td_q.textContent = '問題'; | |
const el_table__head__td_a = document.createElement('td'); | |
el_table__head__td_a.classList.add('quiz-res__head__td'); | |
el_table__head__td_a.textContent = '解答'; | |
el_table__head.appendChild(el_table__head__td_q); | |
el_table__head.appendChild(el_table__head__td_a); | |
el_table_res.appendChild(el_table__head); | |
//問題&解答行 | |
let count_correct = 0; | |
for(let i=0;i<QM.#len_quiz;i++){ | |
const i_answer = el_form.elements['radio'+i].value; | |
const el_tr_res = document.createElement('tr'); | |
//問題列 | |
const el_td_q = document.createElement('td'); | |
el_td_q.classList.add('quiz-res__td'); | |
el_td_q.innerHTML = escHtml(QM.#json[i]['question']).replace(/\n/g,'<br>'); | |
el_tr_res.appendChild(el_td_q); | |
//回答列 | |
const el_td_a = document.createElement('td'); | |
el_td_a.classList.add('quiz-res__td'); | |
const el_td_a__inner = document.createElement('div'); | |
el_td_a__inner.classList.add('quiz-res__td-a__inner'); | |
const el_td_a__mark = document.createElement('div'); | |
el_td_a__mark.classList.add('quiz-res__mark'); | |
const el_td_a__text = document.createElement('div'); | |
el_td_a__text.classList.add('quiz-res__correct'); | |
el_td_a__text.textContent = QM.#json[i]['answers'][QM.#json[i]['index-answer']]; | |
if(i_answer!=''&&i_answer==QM.#json[i]['index-answer']){ | |
//正解 | |
el_td_a__mark.classList.add('quiz-res__maru'); | |
el_td_a__mark.textContent = '◯'; | |
count_correct++; | |
}else{ | |
//不正解 | |
el_td_a__mark.classList.add('quiz-res__batsu'); | |
el_td_a__mark.textContent = '✕'; | |
const el_wrong = document.createElement('div'); | |
el_wrong.classList.add('quiz-res__wrong'); | |
if(i_answer==''){ | |
el_wrong.textContent = '無回答'; | |
}else{ | |
el_wrong.textContent = QM.#json[i]['answers'][i_answer]; | |
} | |
el_td_a__text.prepend(el_wrong); | |
} | |
el_td_a.appendChild(el_td_a__inner); | |
el_td_a__inner.appendChild(el_td_a__mark); | |
el_td_a__inner.appendChild(el_td_a__text); | |
el_tr_res.appendChild(el_td_a); | |
// | |
el_table_res.appendChild(el_tr_res); | |
} | |
//結果まとめ行 | |
const el_tr_sum = document.createElement('tr'); | |
const el_td_sum = document.createElement('td'); | |
el_td_sum.classList.add('quiz-res__td'); | |
el_td_sum.classList.add('quiz-res__td-sum'); | |
el_td_sum.colSpan = '2'; | |
el_td_sum.textContent = `${QM.#len_quiz}問中${count_correct}問正解!`; | |
el_tr_sum.appendChild(el_td_sum); | |
el_table_res.appendChild(el_tr_sum); | |
//表示 | |
el_res.appendChild(el_table_res); | |
QM.#body.classList.add('hide'); | |
//スクロール | |
const pos_res = window.pageYOffset + el_res.getBoundingClientRect().top; | |
window.scrollTo({ | |
top: pos_res, | |
left: 0, | |
behavior: 'smooth' | |
}); | |
} | |
function escHtml(str){ | |
str = str.replace(/&/g, '&') | |
.replace(/</g, '<') | |
.replace(/>/g, '>') | |
.replace(/"/g, '"') | |
.replace(/'/g, '''); | |
return str; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment