├── index.html ├── script.js └── styles.css /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Quiz App 10 | 11 | 12 |
13 |
14 |
Question
15 |
16 | 17 | 18 | 19 | 20 |
21 |
22 |
23 | 24 | 25 |
26 |
27 | 28 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | const startButton = document.getElementById('start-btn') 2 | const nextButton = document.getElementById('next-btn') 3 | const questionContainerElement = document.getElementById('question-container') 4 | const questionElement = document.getElementById('question') 5 | const answerButtonsElement = document.getElementById('answer-buttons') 6 | 7 | let shuffledQuestions, currentQuestionIndex 8 | 9 | startButton.addEventListener('click', startGame) 10 | nextButton.addEventListener('click', () => { 11 | currentQuestionIndex++ 12 | setNextQuestion() 13 | }) 14 | 15 | function startGame() { 16 | startButton.classList.add('hide') 17 | shuffledQuestions = questions.sort(() => Math.random() - .5) 18 | currentQuestionIndex = 0 19 | questionContainerElement.classList.remove('hide') 20 | setNextQuestion() 21 | } 22 | 23 | function setNextQuestion() { 24 | resetState() 25 | showQuestion(shuffledQuestions[currentQuestionIndex]) 26 | } 27 | 28 | function showQuestion(question) { 29 | questionElement.innerText = question.question 30 | question.answers.forEach(answer => { 31 | const button = document.createElement('button') 32 | button.innerText = answer.text 33 | button.classList.add('btn') 34 | if (answer.correct) { 35 | button.dataset.correct = answer.correct 36 | } 37 | button.addEventListener('click', selectAnswer) 38 | answerButtonsElement.appendChild(button) 39 | }) 40 | } 41 | 42 | function resetState() { 43 | clearStatusClass(document.body) 44 | nextButton.classList.add('hide') 45 | while (answerButtonsElement.firstChild) { 46 | answerButtonsElement.removeChild(answerButtonsElement.firstChild) 47 | } 48 | } 49 | 50 | function selectAnswer(e) { 51 | const selectedButton = e.target 52 | const correct = selectedButton.dataset.correct 53 | setStatusClass(document.body, correct) 54 | Array.from(answerButtonsElement.children).forEach(button => { 55 | setStatusClass(button, button.dataset.correct) 56 | }) 57 | if (shuffledQuestions.length > currentQuestionIndex + 1) { 58 | nextButton.classList.remove('hide') 59 | } else { 60 | startButton.innerText = 'Restart' 61 | startButton.classList.remove('hide') 62 | } 63 | } 64 | 65 | function setStatusClass(element, correct) { 66 | clearStatusClass(element) 67 | if (correct) { 68 | element.classList.add('correct') 69 | } else { 70 | element.classList.add('wrong') 71 | } 72 | } 73 | 74 | function clearStatusClass(element) { 75 | element.classList.remove('correct') 76 | element.classList.remove('wrong') 77 | } 78 | 79 | const questions = [ 80 | { 81 | question: 'What is 2 + 2?', 82 | answers: [ 83 | { text: '4', correct: true }, 84 | { text: '22', correct: false } 85 | ] 86 | }, 87 | { 88 | question: 'Who is the best YouTuber?', 89 | answers: [ 90 | { text: 'Web Dev Simplified', correct: true }, 91 | { text: 'Traversy Media', correct: true }, 92 | { text: 'Dev Ed', correct: true }, 93 | { text: 'Fun Fun Function', correct: true } 94 | ] 95 | }, 96 | { 97 | question: 'Is web development fun?', 98 | answers: [ 99 | { text: 'Kinda', correct: false }, 100 | { text: 'YES!!!', correct: true }, 101 | { text: 'Um no', correct: false }, 102 | { text: 'IDK', correct: false } 103 | ] 104 | }, 105 | { 106 | question: 'What is 4 * 2?', 107 | answers: [ 108 | { text: '6', correct: false }, 109 | { text: '8', correct: true } 110 | ] 111 | } 112 | ] -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- 1 | *, *::before, *::after { 2 | box-sizing: border-box; 3 | font-family: Gotham Rounded; 4 | } 5 | 6 | :root { 7 | --hue-neutral: 200; 8 | --hue-wrong: 0; 9 | --hue-correct: 145; 10 | } 11 | 12 | body { 13 | --hue: var(--hue-neutral); 14 | padding: 0; 15 | margin: 0; 16 | display: flex; 17 | width: 100vw; 18 | height: 100vh; 19 | justify-content: center; 20 | align-items: center; 21 | background-color: hsl(var(--hue), 100%, 20%); 22 | } 23 | 24 | body.correct { 25 | --hue: var(--hue-correct); 26 | } 27 | 28 | body.wrong { 29 | --hue: var(--hue-wrong); 30 | } 31 | 32 | .container { 33 | width: 800px; 34 | max-width: 80%; 35 | background-color: white; 36 | border-radius: 5px; 37 | padding: 10px; 38 | box-shadow: 0 0 10px 2px; 39 | } 40 | 41 | .btn-grid { 42 | display: grid; 43 | grid-template-columns: repeat(2, auto); 44 | gap: 10px; 45 | margin: 20px 0; 46 | } 47 | 48 | .btn { 49 | --hue: var(--hue-neutral); 50 | border: 1px solid hsl(var(--hue), 100%, 30%); 51 | background-color: hsl(var(--hue), 100%, 50%); 52 | border-radius: 5px; 53 | padding: 5px 10px; 54 | color: white; 55 | outline: none; 56 | } 57 | 58 | .btn:hover { 59 | border-color: black; 60 | } 61 | 62 | .btn.correct { 63 | --hue: var(--hue-correct); 64 | color: black; 65 | } 66 | 67 | .btn.wrong { 68 | --hue: var(--hue-wrong); 69 | } 70 | 71 | .start-btn, .next-btn { 72 | font-size: 1.5rem; 73 | font-weight: bold; 74 | padding: 10px 20px; 75 | } 76 | 77 | .controls { 78 | display: flex; 79 | justify-content: center; 80 | align-items: center; 81 | } 82 | 83 | .hide { 84 | display: none; 85 | } --------------------------------------------------------------------------------