Skip to content

Commit a853771

Browse files
authored
Merge pull request #72 from sabin-khatri/sabin
Add Quiz app using HTML CSS anD JS
2 parents a068a4d + f9e4364 commit a853771

6 files changed

Lines changed: 414 additions & 0 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Modern Stopwatch</title>
7+
<link rel="stylesheet" href="style.css">
8+
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@500&display=swap" rel="stylesheet">
9+
</head>
10+
<body>
11+
<main class="stopwatch">
12+
<div class="timer" id="timer">00 : 00 : 00</div>
13+
14+
<div class="controls">
15+
<button id="startBtn" class="btn" data-color="green">Start</button>
16+
<button id="stopBtn" class="btn" data-color="red">Stop</button>
17+
<button id="resetBtn" class="btn" data-color="blue">Reset</button>
18+
</div>
19+
</main>
20+
21+
<script src="script.js"></script>
22+
</body>
23+
</html>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
const timerEl = document.getElementById('timer');
3+
const startBtn = document.getElementById('startBtn');
4+
const stopBtn = document.getElementById('stopBtn');
5+
const resetBtn = document.getElementById('resetBtn');
6+
const container = document.querySelector('.stopwatch');
7+
8+
9+
let ms = 0, secs = 0, mins = 0;
10+
let running = false;
11+
let rafId = null;
12+
13+
14+
const pad = n => (n < 10 ? `0${n}` : n);
15+
16+
17+
const render = () => {
18+
timerEl.textContent = `${pad(mins)} : ${pad(secs)} : ${pad(ms)}`;
19+
};
20+
21+
let last = 0;
22+
const tick = now => {
23+
if (!last) last = now;
24+
const delta = now - last;
25+
26+
if (delta >= 10) {
27+
ms++;
28+
if (ms === 100) { ms = 0; secs++; }
29+
if (secs === 60) { secs = 0; mins++; }
30+
render();
31+
last = now;
32+
}
33+
rafId = requestAnimationFrame(tick);
34+
};
35+
36+
37+
startBtn.addEventListener('click', () => {
38+
if (running) return;
39+
running = true;
40+
container.classList.add('running');
41+
last = 0;
42+
rafId = requestAnimationFrame(tick);
43+
});
44+
45+
stopBtn.addEventListener('click', () => {
46+
if (!running) return;
47+
running = false;
48+
container.classList.remove('running');
49+
cancelAnimationFrame(rafId);
50+
});
51+
52+
resetBtn.addEventListener('click', () => {
53+
running = false;
54+
container.classList.remove('running');
55+
cancelAnimationFrame(rafId);
56+
ms = secs = mins = 0;
57+
render();
58+
});
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
2+
*,
3+
*::before,
4+
*::after {
5+
margin: 0;
6+
padding: 0;
7+
box-sizing: border-box;
8+
}
9+
10+
html { font-family: 'Roboto Mono', monospace; }
11+
12+
body {
13+
min-height: 100vh;
14+
background: linear-gradient(135deg, #1e3c72, #2a5298);
15+
color: #fff;
16+
display: flex;
17+
align-items: center;
18+
justify-content: center;
19+
overflow: hidden;
20+
}
21+
22+
.stopwatch {
23+
background: rgba(255, 255, 255, 0.12);
24+
backdrop-filter: blur(12px);
25+
-webkit-backdrop-filter: blur(12px);
26+
border-radius: 20px;
27+
padding: 2rem 2.5rem;
28+
box-shadow: 0 8px 32px rgba(0,0,0,.37);
29+
text-align: center;
30+
max-width: 90vw;
31+
width: 360px;
32+
transition: transform .3s ease;
33+
}
34+
35+
.timer {
36+
font-size: clamp(2.5rem, 8vw, 4rem);
37+
font-weight: 500;
38+
letter-spacing: .08em;
39+
margin-bottom: .8rem;
40+
user-select: none;
41+
}
42+
43+
.stopwatch.running .timer {
44+
animation: pulse 1.2s infinite ease-in-out;
45+
}
46+
@keyframes pulse {
47+
0%, 100% { transform: scale(1); }
48+
50% { transform: scale(1.04); }
49+
}
50+
51+
52+
.controls {
53+
display: flex;
54+
gap: .8rem;
55+
justify-content: center;
56+
flex-wrap: wrap;
57+
}
58+
59+
.btn {
60+
--clr: #555;
61+
background: var(--clr);
62+
color: #fff;
63+
border: none;
64+
border-radius: 12px;
65+
padding: .9rem 1.6rem;
66+
font-size: 1rem;
67+
font-weight: 600;
68+
cursor: pointer;
69+
transition: all .25s cubic-bezier(.4,0,.2,1);
70+
position: relative;
71+
overflow: hidden;
72+
min-width: 90px;
73+
}
74+
75+
76+
.btn[data-color="green"] { --clr: #4caf50; }
77+
.btn[data-color="red"] { --clr: #f44336; }
78+
.btn[data-color="blue"] { --clr: #2196f3; }
79+
80+
81+
.btn::after {
82+
content: "";
83+
position: absolute;
84+
inset: 0;
85+
background: rgba(255,255,255,.3);
86+
border-radius: inherit;
87+
transform: scale(0);
88+
transition: transform .4s ease;
89+
}
90+
.btn:active::after { transform: scale(2); opacity: 0; transition: 0s; }
91+
92+
.btn:hover,
93+
.btn:focus-visible {
94+
transform: translateY(-3px);
95+
box-shadow: 0 6px 20px rgba(0,0,0,.3);
96+
}
97+
98+
@media (max-width: 380px) {
99+
.stopwatch { padding: 1.5rem; }
100+
.btn { padding: .7rem 1.2rem; font-size: .9rem; }
101+
}

web/Quiz App/index.html

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Quiz App using Javascript</title>
7+
<link rel="stylesheet" href="style.css">
8+
</head>
9+
<body>
10+
<div class="quiz-container">
11+
<div id="quiz">
12+
<h2 id="question">Question Text</h2>
13+
<ul>
14+
<li>
15+
<input type="radio" name="answer" id="a" class="answer" >
16+
<label for="a" id="a_text" >Answer A</label>
17+
</li>
18+
<li>
19+
<input type="radio" name="answer" id="b" class="answer">
20+
<label for="b" id="b_text">Answer B</label>
21+
</li>
22+
23+
<li>
24+
<input type="radio" name="answer" id="c" class="answer">
25+
<label for="c" id="c_text">Answer C</label>
26+
</li>
27+
28+
<li>
29+
<input type="radio" name="answer" id="d" class="answer">
30+
<label for="d" id="d_text">Answer D</label>
31+
</li>
32+
</ul>
33+
<button id="submit">Submit</button>
34+
</div>
35+
</div>
36+
<script src="script.js"></script>
37+
</body>
38+
</html>

web/Quiz App/script.js

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
const quizData = [
2+
{
3+
question: "Which of the following is not a JavaScript Data Type?",
4+
a: "Undefined",
5+
b: "Number",
6+
c: "Boolean",
7+
d: "Float",
8+
correct: "d",
9+
},
10+
{
11+
question: "Which company developed JavaScript?",
12+
a: "Netscape",
13+
b: "Bell Labs",
14+
c: "Sun Microsystems",
15+
d: "IBM",
16+
correct: "a",
17+
},
18+
{
19+
question: "Inside which HTML element do we put the JavaScript?",
20+
a: "<script>",
21+
b: "<head>",
22+
c: "<meta>",
23+
d: "<style>",
24+
correct: "a",
25+
},
26+
{
27+
question: "Which one is the ternary operator in JavaScript?",
28+
a: "#",
29+
b: "::",
30+
c: "&:",
31+
d: "?:",
32+
correct: "d",
33+
},
34+
{
35+
question: "Which symbol is used for comments in JavaScript?",
36+
a: "\\",
37+
b: "//",
38+
c: "/* */",
39+
d: "*/",
40+
correct: "b",
41+
},
42+
{
43+
question: "What are the types of pop-up boxes available in JavaScript?",
44+
a: "Alert",
45+
b: "Prompt",
46+
c: "Confirm",
47+
d: "All of the above",
48+
correct: "d",
49+
},
50+
{
51+
question: "Which of the following methods checks if its argument is not a number?",
52+
a: "isNaN()",
53+
b: "nonNaN()",
54+
c: "NaN()",
55+
d: "None of the above",
56+
correct: "a",
57+
},
58+
];
59+
60+
const quiz = document.getElementById('quiz');
61+
const questionEl = document.getElementById('question');
62+
const a_text = document.getElementById('a_text');
63+
const b_text = document.getElementById('b_text');
64+
const c_text = document.getElementById('c_text');
65+
const d_text = document.getElementById('d_text');
66+
const submitBtn = document.getElementById('submit');
67+
const answerEls = document.querySelectorAll('.answer');
68+
69+
let currentQuiz = 0;
70+
let score = 0;
71+
let answers = [];
72+
73+
loadQuiz();
74+
75+
function loadQuiz() {
76+
deselectAnswers();
77+
const currentQuizData = quizData[currentQuiz];
78+
questionEl.innerText = currentQuizData.question;
79+
a_text.innerText = currentQuizData.a;
80+
b_text.innerText = currentQuizData.b;
81+
c_text.innerText = currentQuizData.c;
82+
d_text.innerText = currentQuizData.d;
83+
}
84+
85+
function getSelected() {
86+
let answer = undefined;
87+
answerEls.forEach(answerEl => {
88+
if (answerEl.checked) {
89+
answer = answerEl.id;
90+
}
91+
});
92+
return answer;
93+
}
94+
95+
function deselectAnswers() {
96+
answerEls.forEach(answerEl => {
97+
answerEl.checked = false;
98+
});
99+
}
100+
101+
submitBtn.addEventListener('click', () => {
102+
const answer = getSelected();
103+
104+
if (answer) {
105+
// Save the user's answer
106+
answers.push({ question: quizData[currentQuiz].question, answer, correctAnswer: quizData[currentQuiz].correct });
107+
108+
if (answer === quizData[currentQuiz].correct) {
109+
score++;
110+
}
111+
112+
currentQuiz++;
113+
114+
if (currentQuiz < quizData.length) {
115+
loadQuiz();
116+
} else {
117+
// Show quiz result
118+
showResult();
119+
}
120+
}
121+
});
122+
123+
function showResult() {
124+
quiz.innerHTML = `
125+
<h2>You answered ${score}/${quizData.length} questions correctly</h2>
126+
<ul>
127+
${answers.map((ans, index) => `
128+
<li class="${ans.answer === ans.correctAnswer ? 'correct' : 'wrong'}">
129+
<strong>Question ${index + 1}:</strong> ${ans.question} <br>
130+
<span>Your answer: ${ans.answer.toUpperCase()}</span> <br>
131+
<span>Correct answer: ${ans.correctAnswer.toUpperCase()}</span>
132+
</li>
133+
`).join('')}
134+
</ul>
135+
<button onclick="location.reload()">Replay</button>
136+
`;
137+
}
138+

0 commit comments

Comments
 (0)