sector_megamenu-1.0.2/components/megamenu/body/body.js
components/megamenu/body/body.js
const trapFocus = (e, x) => {
const dialog = e.srcElement.closest('dialog')
if (e.key === "Tab") {
e.preventDefault();
const focusableElements = dialog.querySelectorAll(
'a[href], button, textarea, input, select'
);
// Convert NodeList to array
const focusableElementsArray = Array.from(focusableElements);
// Get the index of the currently focused element
const currentIndex = focusableElementsArray.indexOf(document.activeElement);
// Calculate the next focus index
const nextIndex = (currentIndex + 1) % focusableElementsArray.length;
// Set focus to the next focusable element
focusableElementsArray[nextIndex].focus();
}
};
// Function to check if any ancestor of an element has a specific class
function hasAncestorWithClass(element, classNames) {
var node = element.parentNode;
while (node !== null) {
if (node.classList) {
for (var i = 0; i < classNames.length; i++) {
if (node.classList.contains(classNames[i])) {
return true;
}
}
}
node = node.parentNode;
}
return false;
}
window.addEventListener('load', () => {
const megamenuRootButtonHandler = new CustomEvent('megamenuRootButtonHandler', {
bubbles: true, // Specifies whether the event bubbles up through the DOM or not
cancelable: true // Specifies whether the event is cancelable or not
});
const megaMenuBodies = document.querySelectorAll('.mega-menu-body__item');
if (megaMenuBodies.length === 0) {
return;
}
megaMenuBodies.forEach((megaMenuBody) => {
const id = megaMenuBody.getAttribute('id')
const others = document.querySelectorAll(`.mega-menu-body__item:not([id="${id}"])`)
megaMenuBody.addEventListener('megamenuBodyHandler', function(event) {
others.forEach((otherMegaMenuBody) => {
otherMegaMenuBody.setAttribute('aria-expanded', 'false');
otherMegaMenuBody.setAttribute('aria-hidden', 'true');
otherMegaMenuBody.removeEventListener("keydown", trapFocus);
otherMegaMenuBody.close();
})
switch(event.action) {
case 'open' :
megaMenuBody.setAttribute('aria-expanded', 'true');
megaMenuBody.setAttribute('aria-hidden', 'false');
megaMenuBody.show();
megaMenuBody.addEventListener("keydown", trapFocus);
//megaMenuBody.querySelector('.mega-menu__heading-link').focus();
break;
default:
megaMenuBody.setAttribute('aria-expanded', 'false');
megaMenuBody.setAttribute('aria-hidden', 'true');
megaMenuBody.close();
megaMenuBody.removeEventListener("keydown", trapFocus);
break;
}
});
const close = document.createElement('button');
close.setAttribute('type', 'button');
close.innerHTML = `<span>Close menu</span><span class="material-symbols-sharp" aria-hidden="true">close</span>`
close.classList.add('mega-menu-body__close')
megaMenuBody.appendChild(close);
close.addEventListener('click', () => {
megaMenuBody.close()
})
megaMenuBody.addEventListener('close', () => {
const rootButton = document.querySelector(`.mega-menu__toggle[aria-controls="${id}"]`)
rootButton.dispatchEvent(megamenuRootButtonHandler)
// root button needs aria-expanded = false
})
});
document.addEventListener('keyup', function(event) {
if (event.key === 'Escape' || event.key === 'Esc') {
megaMenuBodies.forEach((body) => {
body.setAttribute('aria-expanded', 'false');
body.setAttribute('aria-hidden', 'true');
body.close();
body.removeEventListener("keydown", trapFocus);
})
}
});
['mousedown', 'touchstart'].forEach((event) => {
document.addEventListener(event, ({ target }) => {
const isInsideMegamenuBody = hasAncestorWithClass(target, ['mega-menu-body', 'mega-menu-root', 'contextual']);
if(isInsideMegamenuBody === false) {
megaMenuBodies.forEach((body) => {
body.setAttribute('aria-expanded', 'false');
body.setAttribute('aria-hidden', 'true');
body.close();
body.removeEventListener("keydown", trapFocus);
})
}
})
});
})