Quiz Prototype
I've been thinking about building an online vocabulary quiz for the students that my wife and I teach English to every once in a while. So I built my first prototype. This was an interesting exercise and I feel like I will be able build out a viable version with a couple of more hours of work.
Vocabulary Quiz 単語のクイズ
Word
View the code:
HTML and JS
<section class="code-block">
<div class="wrapper">
<h1>Vocabulary Quiz <span lang="ja">単語のクイズ</span></h1>
<aside id="questionTracker" hidden><p>#<span id="currentQuestion">1</span>/<span id="questionsTotal">10</span></p></aside>
<img id="wordPhoto" class="hideOnStart" src="https://www.jeremycaudle.com/floorshotJC.jpeg" width='360' height="240" alt="Cat photo from placekitten" />
<h2 id="vocabWord" hidden>Word</h2>
<div class="answers" hidden>
<button id="answer1" lang="ja">Answer 1</button><button id="answer2" lang="ja">Answer 2</button><button id="answer3" lang="ja">Answer 3</button><button id="answer4" lang="ja">Answer 4</button>
</div>
<button id="startBtn" class="startButton">Start Quiz</button>
<button id="nextBtn" class="nextButton hideOnStart">Next Word</button>
</div>
</section>
<script>
// Store buttons in variables
const startBtn = document.querySelector('#startBtn');
const nextBtn = document.querySelector('#nextBtn');
let vocabWord = document.querySelector('#vocabWord');
let answer1 = document.querySelector('#answer1');
let answer2 = document.querySelector('#answer2');
let answer3 = document.querySelector('#answer3');
let answer4 = document.querySelector('#answer4');
const elementList = document.querySelectorAll('[hidden], .hideOnStart');
let currentQuestion = document.querySelector('#currentQuestion');
// Functions
function unhideAll() {
for (let i = 0; i < elementList.length; i++) {
if(elementList[i].className === "hideOnStart") {
console.log(i);
elementList[i].removeAttribute('class');
} else {
elementList[i].toggleAttribute('hidden');
}
};
vocabWord.textContent = 'cat';
answer1.textContent = 'ねこ';
answer2.textContent = 'いぬ';
answer3.textContent = 'りす';
answer4.textContent = 'ねずみ';
startBtn.className = "hideOnStart";
}
function updateQA(questionNum, word, answer1, answer2, answer3, answer4) {
currentQuestion.textContent = questionNum;
vocabWord.textContent = word;
answer1.textContent = answer1;
answer2.textContent = answer2;
answer3.textContent = answer3;
answer4.textContent = answer4;
}
// Listen for events
startBtn.addEventListener('click', () => {
unhideAll();
});
answer1.addEventListener('click', () => {
answer1.toggleAttribute('disabled');
answer1.setAttribute('class','correctAnswer');
nextBtn.setAttribute('class','nextButton');
});
answer2.addEventListener('click', () => {
answer2.toggleAttribute('disabled');
answer2.setAttribute('class','wrongAnswer');
});
answer3.addEventListener('click', () => {
answer3.toggleAttribute('disabled');
answer3.setAttribute('class','wrongAnswer');
});
answer4.addEventListener('click', () => {
answer4.toggleAttribute('disabled');
answer4.setAttribute('class','wrongAnswer');
});
nextBtn.addEventListener('click', () => {
updateQA(2, 'dog', 'いぬ', 'ねこ', 'りす', 'ねずみ');
answer1.removeAttribute('class');
answer1.toggleAttribute('disabled');
answer2.removeAttribute('class');
answer2.toggleAttribute('disabled');
answer3.removeAttribute('class');
answer3.toggleAttribute('disabled');
answer4.removeAttribute('class');
answer4.toggleAttribute('disabled');
nextBtn.setAttribute('class', 'hideOnStart');
});
</script>
CSS
/* Variables */
:root {
--bg-color: #111;
--bg-secondary: white;
--text-color: #232323;
--radius-main: 1rem;
}
/* Animations */
/* Class for CMS */
.code-block {
font-family: Verdana, Geneva, Tahoma, sans-serif;
background: var(--bg-color, slateblue);
z-index: 1;
padding: 1rem;
max-width: 60em;
margin: 0 auto;
transition: all .25s ease-out;
}
/* Elements */
.code-block h1 { color:white; position: relative; display: block; font-size: 2rem; margin-bottom: 3rem; }
.code-block h1 span[lang="ja"] {display: block; color: gray; position: absolute; top: 2.25rem; font-size: .66em; right: 0;}
.code-block h2 {text-align: center; color: white;}
img {
display: block;
width: 100%;
max-width: 100%;
height: auto;
border-radius: var(--radius-main, 1rem);
}
button {
border-radius: var(--radius-main, 1rem);
border: 0;
padding: .75rem 1.5rem;
margin: .75rem;
width: calc(50% - 1.5rem);
display: inline-block;
transition: transform .125s ease-out;
font-size: 1.5rem;
font-weight: bold;
background-color: gray;
}
button:hover {
background: yellow;
color: blue;
}
button:active {
transform: scale(.99);
}
/* Custom Classes */
.wrapper {
position: relative;
}
.startButton {
display: block;
margin: 1rem auto;
width: auto;
max-width: 20em;
background-color: green;
font-size: 1.125rem;
}
.nextButton {
display: block;
margin: 1rem auto;
width: auto;
max-width: 20em;
font-size: 1.125rem;
}
.hideOnStart {
display: none;
}
.wrongAnswer {
background: rgb(209, 72, 72);
color: white;
transform: rotate(-3deg) scale(.75);
}
.correctAnswer {
color: rgb(110, 31, 0);
background-color: gold;
transform: scale(1.05);
box-shadow: 0 0 10px 10px rgba(255, 217, 0, 0.5);
}
/* IDs */
#questionTracker {
color: white;
}
/* Support Queries */
/* @supports (display: flex) {
#buttons {
display: flex;
flex-flow: column;
justify-content: space-evenly;
}
} */
/* @supports (display: grid) {
.code-block {
display: grid;
min-height: 100vh;
place-items: center;
}
.wrapper {
display: grid;
max-width: 60em;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: 5em repeat(2, 1fr);
grid-gap: 1rem;
background: rgba(0,0,0,0.2);
place-items: center;
}
h1 {
grid-column: 1 / 6;
}
} */