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);
                })
            }
        })
    });
})

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc