I created a multi-page quiz, and I use the sessionStorage API to calculate the points and display the final score on the last page. Each time, I have a first page with the quiz.
<form id="q1">
<fieldset>
<p>
<input type="radio" id="q1resp1" name="q1resp">
<label for="q1resp1">Answer one</label>
</p>
<p>
<input type="radio" id="q1resp2" name="q1resp">
<label for="q1resp2">Answer two</label>
</p>
<p>
<input type="radio" id="q1resp3" name="q1resp" checked>
<label for="q1resp3">MAnswer three</label>
</p>
</fieldset>
</form>
<script>
const handleSubmit = function () {
const check1 = document.getElementById("q4resp1").checked;
const check2 = document.getElementById("q4resp2").checked;
const check3 = document.getElementById("q4resp3").checked;
const q4 = {
1: check1,
2: check2,
3: check3,
};
window.sessionStorage.setItem("q1", JSON.stringify(q1));
window.location.href = "question-1-answer.html";
};
buttons.forEach((button) => {
button.addEventListener("click", (e) => {
e.preventDefault();
handleSubmit();
});
});
</script>
Then a second page with the answer :
<script>
const previousChecks = JSON.parse(window.sessionStorage.getItem("q1"));
let score = Number(window.sessionStorage.getItem("score"));
if (!previousChecks[3]) {
score += 1;
window.sessionStorage.setItem("score", String(score));
}
</script>
I therefore have two pages for each step of the quiz. (one question page, one answer page, one question page, one answer page, etc.).
At the very end, I indicate the final score.
<script>
const score = window.sessionStorage.getItem("score");
document.getElementById("result").innerHTML = score === 0 ? 0 : (score * 100) / 5 + "%";
</script>
The problem: once the quiz is finished, if I click the back button of the browser to return to the last question (so two pages back), it will automatically take the previous point, saved in the session, and add it to the final score.
I would therefore like that when the user goes back to question 5, it cancels the points they have accumulated for question 5. If they go back to question 4, it cancels the accumulated points for questions 4 and 5, and so on. This is to ensure a reliable result and never exceed 100%.
I tried with window.addEventListener('beforeunload', () => {});but I can't figure out the logic to apply. Should I target the question page or the answer page? How can I make it so that the points are canceled if there have been any, but not taken away if there haven't been any?
Any help would be appreciated.
EDIT: Thanks to Rajeev's answer, I was able to make it work. But as soon as I add an if else statement to include a success message, it no longer works. Any idea why?
here is the modified code :
let q1 = JSON.parse(sessionStorage.getItem('q1'));
let score = Number(sessionStorage.getItem('score')) || 0;
if (!q1.scored) {
if (q1[1] && q1[2]){
score++;
document.querySelector('#correct').style.display = "block";
q1.scored = true;
sessionStorage.setItem('q1', JSON.stringify(q1));
sessionStorage.setItem('score', score);
}else{
document.querySelector('#wrong').style.display = "block";
}
}
Now, if I go back, the new points are added to the previous ones. I end up with scores like 120%, 180%, etc.
When you store the answer --> set scored:false
.
On the answer page --> only add points if scored
is still false, then mark it true.
This way each question only contributes once, no matter how many times you revisit the page.
// question page
sessionStorage.setItem('q1', JSON.stringify({
1: q1resp1.checked,
2: q1resp2.checked,
3: q1resp3.checked,
scored: false
}));
// answer page
let q1 = JSON.parse(sessionStorage.getItem('q1'));
let score = Number(sessionStorage.getItem('score')) || 0;
if (!q1.scored) {
if (q1[3]) score++;
q1.scored = true;
sessionStorage.setItem('q1', JSON.stringify(q1));
sessionStorage.setItem('score', score);
}
Now the score won’t increase again when navigating with the back button.