Handling Multiple Modals on One Page with Vanilla JS

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

Published: Feb 16, 2018

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">&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) {
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.


More from my blog

All Blog Articles →