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("q1resp1").checked;
const check2 = document.getElementById("q1resp2").checked;
const check3 = document.getElementById("q1resp3").checked;
const q1 = {
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.
I would do something like this, check if you have already scored the question:
const previousChecks = JSON.parse(window.sessionStorage.getItem('q1'));
let score = Number(window.sessionStorage.getItem('score')) || 0;
// Check if question was already scored
const scoredQuestions = JSON.parse(window.sessionStorage.getItem('scoredQuestions')) || {};
if (!scoredQuestions['q1'] && previousChecks[3]) {
score += 1;
scoredQuestions['q1'] = true;
window.sessionStorage.setItem('score', String(score));
window.sessionStorage.setItem('scoredQuestions', JSON.stringify(scoredQuestions));
}