This discussion has been helpful. Thanks Paul for helping to reveal that the error occurs when you click on the same element again.
I’ve noticed that nothing happens the first time that you click on an element. That problem occurs because the switch code in the click handler creates a new click handler on the element. Later on when you click on that element again, it triggers the click handler, but it also causes another click handler to also be created.
Remove unwanted click handlers
Removing the click handlers that are created in the switch code,results in the following simpler code. I’ve also removed global variables and just defined the variable where they’re used.
var currentEl = e.target || e.srcElement;
switch (currentEl.id) {
case "choice":
OptionsModal = new bootstrap.Modal(document.getElementById(currentEl.id + "Modal"));
OptionsModal.show();
break;
case "choice1":
OptionsModal = new bootstrap.Modal(document.getElementById(currentEl.id + "Modal"));
OptionsModal.show();
break;
case "choice2":
OptionsModal = new bootstrap.Modal(document.getElementById(currentEl.id + "Modal"));
OptionsModal.show();
break;
case "choice3":
OptionsModal = new bootstrap.Modal(document.getElementById(currentEl.id + "Modal"));
OptionsModal.show();
break;
case 'choice4':
OptionsModal = new bootstrap.Modal(document.getElementById(currentEl.id + "Modal"));
OptionsModal.show();
break;
}
That code works well with no errors.
Solving problems by deletion - I love it.
Remove duplicate switch statements
Those switch statements are all the same now, so we can remove the switch code and use a simple guard clause instead:
var currentEl = e.target || e.srcElement;
if (!currentEl.id.includes("choice")) {
return;
}
var OptionsModal = new bootstrap.Modal(document.getElementById(currentEl.id + "Modal"));
OptionsModal.show();
Remove the need for a guard clause
Can we get rid of the guard clause? It’s protecting against non-choice clicks. We should be able to update the click handler so that only the choice elements are involved:
Here I’ve moved the event handler function out to a separately named function, so that it’s the same function that gets assigned each time in the loop.
As each choice element is a div inside of the choices body, and there are no other divs to confuse things, we can just loop through each of those divs assigning the same showModal click handler to them.
function showModal(e) {
var currentEl = e.target || e.srcElement;
var OptionsModal = new bootstrap.Modal(document.getElementById(currentEl.id + "Modal"));
OptionsModal.show();
}
document.querySelectorAll("#choices .modal-body div").forEach(function (div) {
div.addEventListener("click", showModal, false);
});
Conclusion
There doesn’t seem to be anything else worth removing. The problem looks to be solved, and we have reduced all of the JS code to just the following:
var instructionsModal = new bootstrap.Modal(document.getElementById("instructions"));
instructionsModal.show();
window.addEventListener('contextmenu', (event) => {
event.preventDefault();
var choicesModal = new bootstrap.Modal(document.getElementById("choices"));
choicesModal.show();
});
function showModal(e) {
var currentEl = e.target || e.srcElement;
var OptionsModal = new bootstrap.Modal(document.getElementById(currentEl.id + "Modal"));
OptionsModal.show();
}
document.querySelectorAll("#choices .modal-body div").forEach(function (div) {
div.addEventListener("click", showModal, false);
});