I'm working on a trap focus modal functionality and it works well with a single element, but I can't get it working with multiple elements. It traps focus only on last modal. I know there is something wrong with my loop, I tried to catch activeElement and add a condition if it's equal to focused element but with no result.
Here is the CodePen example
HTML
<div class="container">
<div class="nav__mobile">
<div class="nav__right-item">
<div class="everse-menu-search">
<a href="#" class="everse-menu-search__trigger" title="Search">Mobile Search</a>
<div class="everse-menu-search-modal">
<div class="everse-menu-search-modal__inner">
<div class="container">
<form role="search" method="get" class="search-form relative" action="//localhost:3000/">
<label>
<span class="screen-reader-text">Search for:</span>
<input type="search" class="search-input" placeholder="Search" value="" name="s">
</label>
<button type="button" class="everse-menu-search-modal__close" aria-label="Close Search">
<span>Close</span>
</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="everse-menu-search">
<a href="#" class="everse-menu-search__trigger" title="Search">Search</a>
<div class="everse-menu-search-modal">
<div class="everse-menu-search-modal__inner">
<div class="container">
<form role="search" method="get" class="search-form relative" action="//localhost:3000/">
<label>
<span class="screen-reader-text">Search for:</span>
<input type="search" class="search-input" placeholder="Search" value="" name="s">
</label>
<button type="button" class="everse-menu-search-modal__close" aria-label="Close Search"><span>Close</span>
</button>
</form>
</div>
</div>
</div>
</div>
</div>
JavaScript
(function(){
var html = document.querySelector('html'),
body = document.body;
mobileAccessibility();
menuSearch();
function mobileAccessibility() {
document.addEventListener('keydown', function(e) {
var tabKey, shiftKey, selectors, activeEl, lastEl, firstEl;
if ( body.classList.contains('showing-modal') ) {
selectors = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
activeEl = document.activeElement;
// Search
if ( body.classList.contains( 'showing-search-modal' ) ) {
let search = document.querySelectorAll('.everse-menu-search:not(.eversor-menu-search)');
for ( var i = 0; i < search.length; i++ ) {
var input = search[i].querySelector('.search-input');
var close = search[i].querySelector('.everse-menu-search-modal__close');
firstEl = input;
lastEl = close;
}
}
tabKey = e.key === 'Tab' || e.keyCode === 9;
shiftKey = e.shiftKey
if ( ! shiftKey && tabKey && lastEl === activeEl ) {
e.preventDefault();
firstEl.focus();
}
if ( shiftKey && tabKey && firstEl === activeEl ) {
e.preventDefault();
lastEl.focus();
}
}
});
}
function menuSearch() {
let search = document.querySelectorAll('.everse-menu-search:not(.eversor-menu-search)');
if ( ! search.length > 0 ) {
return;
}
for ( var i = 0; i < search.length; i++ ) {
let trigger = search[i].querySelector('.everse-menu-search__trigger'),
modal = search[i].querySelector('.everse-menu-search-modal'),
inner = search[i].querySelector('.everse-menu-search-modal__inner'),
input = search[i].querySelector('.search-input'),
close = search[i].querySelector('.everse-menu-search-modal__close');
trigger.addEventListener('click', function(e) {
e.preventDefault();
body.classList.toggle('showing-modal');
body.classList.toggle('showing-search-modal');
modal.classList.add('everse-menu-search-modal--is-open');
setTimeout(() => {
input.focus();
}, 200);
});
inner.addEventListener('click', function(e) {
e.stopPropagation();
});
modal.addEventListener('click', function(e) {
closeModal(this);
});
close.addEventListener('click', function(e) {
closeModal(modal);
});
/*
* Close on click or on esc.
*/
document.addEventListener('keyup', function(e) {
if ( 27 === e.keyCode ) {
closeModal(modal);
}
});
}
function closeModal(modal) {
body.classList.remove('showing-modal');
body.classList.remove('showing-search-modal');
modal.classList.remove('everse-menu-search-modal--is-open');
}
}
})();