Sometimes I need to add multiple modal overlays to an single web page. I’ll show you a way to do so that quickly gets out of hand – and a better way that is more manageable.
DONT: Give each modal and trigger IDs
Giving each modal an unique ID bloats up the code and makes it more error-prone.
<!-- Elements used for triggering modals to open -->
<button class="modal-trigger" id="modal-0-trigger"></button>
<button class="modal-trigger" id="modal-1-trigger"></button>
<button class="modal-trigger" id="modal-2-trigger"></button>
<!-- Elements used as modals -->
<div id="modal-0" class="modal">...</div>
<div id="modal-1" class="modal">...</div>
<div id="modal-2" class="modal">...</div>
let modal0 = document.getElementById('modal-0');
let modal1 = document.getElementById('modal-1');
let modal2 = document.getElementById('modal-2');
let modal0Trigger = document.getElementById('modal-0-trigger');
let modal1Trigger = document.getElementById('modal-1-trigger');
let modal2Trigger = document.getElementById('modal-2-trigger');
function toggleModal() {
...
}
...
DO: Use For...Of-Loops for Modals
So instead of explicitly naming and calling each modal, modal trigger and close button, I just use class names. That makes it easy to create modal templates or components.
<!-- Elements used for triggering modals to open -->
<button class="trigger">Modal 0</button>
<button class="trigger">Modal 1</button>
<button class="trigger">Modal 2</button>
<!-- Elements used as modals -->
<div class="modal">
<span class="btn-close">×</span>
<!-- Content -->
</div>
<div class="modal">
<span class="btn-close">×</span>
<!-- Content -->
</div>
<div class="modal">
<span class="btn-close">×</span>
<!-- Content -->
</div>
In the JavaScript, I use arrays and for...of
-loops to get the modals and show/hide them on click:
// Get each modal and close button
const triggers = document.getElementsByClassName("trigger");
const triggerArray = Array.from(triggers).entries();
const modals = document.getElementsByClassName("modal");
const closeButtons = document.getElementsByClassName("btn-close");
// Then use `for...of`-loop with the index of each item in `triggerArray` for listening to a click event which toggles each modal to open and close
for (let [index, trigger] of triggerArray) {
const toggleModal => () {
modals[index].classList.toggle("show-modal");
};
trigger.addEventListener("click", toggleModal);
closeButtons[index].addEventListener("click", toggleModal);
}
The result:
See the Pen Loop to get modals by screenspan (@screenspan) on CodePen.