Handling Multiple Modals on One Page with Vanilla JS

Here is a little JS snippet for opening and closing multiple modals on a page

Sometimes I have little prototypes or one-pagers that have multiple modal overlays.

Giving each modal an unique ID bloats up the code and gets out of hand – especially if you’re using vanilla JavaScript:

<!-- 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() {
...
}

...

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">&times;</span>
<!-- Content -->
</div>
<div class="modal">
<span class="btn-close">&times;</span>
<!-- Content -->
</div>
<div class="modal">
<span class="btn-close">&times;</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) {
let triggerIndex = index;
function toggleModal() {
// Optionally toggle a class for CSS animations
modals[triggerIndex].classList.toggle("show-modal");
}
trigger.addEventListener("click", toggleModal);
closeButtons[triggerIndex].addEventListener("click", toggleModal);
}

The result:

See the Pen Loop to get modals by screenspan (@screenspan) on CodePen.


Published: Feb 16, 2018

More from my blog