导航选项卡W3C

时间:2019-12-11 09:27:33

标签: javascript accessibility

我已采用符合可访问性的W3C javascript进行选项卡式浏览。它可以正常工作,但是如果我添加多个标签页,我想知道当您位于其中一个框内时是否可以执行此操作,那么您所停留的最后一张图像将始终保留在另一个标签中。因为按原样,当选择一个图像时,它将隐藏其余图像。 javascript如下:

 /*
     *   This content is licensed according to the W3C Software License at
     *   https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
     */
    (function () {
        var tablist = document.querySelectorAll('[role="tablist"]')[0];
        var tabs;
        var panels;
        var delay = determineDelay();

        generateArrays();

        function generateArrays () {
            tabs = document.querySelectorAll('[role="tab"]');
            panels = document.querySelectorAll('[role="tabpanel"]');
        };

        // Para facilitar la referencia
        var keys = {
            end: 35,
            home: 36,
            left: 37,
            up: 38,
            right: 39,
            down: 40,
            delete: 46
        };

        // Agregar o restar dependiendo de la tecla presionada
        var direction = {
            37: -1,
            38: -1,
            39: 1,
            40: 1
        };

        // Listeners
        for (i = 0; i < tabs.length; ++i) {
            addListeners(i);
        };

        function addListeners (index) {
            tabs[index].addEventListener('click', clickEventListener);
            tabs[index].addEventListener('keydown', keydownEventListener);
            tabs[index].addEventListener('keyup', keyupEventListener);

            // Crear un array con todas las tabs (botón) en ella
            tabs[index].index = index;
        };

        // Cuando se hace clic en una tab, activeTab se dispara para activarla
        function clickEventListener (event) {
            var tab = event.target;
            activateTab(tab, false);
        };

        // Manejar keydown en tabs
        function keydownEventListener (event) {
            var key = event.keyCode;

            switch (key) {
                case keys.end:
                    event.preventDefault();
                    // Activar última tab
                    activateTab(tabs[tabs.length - 1]);
                    break;
                case keys.home:
                    event.preventDefault();
                    // Activar primera tab
                    activateTab(tabs[0]);
                    break;

                // Arriba y abajo están en keydown
                // se necesita evitar scroll en página
                case keys.up:
                case keys.down:
                    determineOrientation(event);
                    break;
            };
        };

        // Manejar keyup en tabs
        function keyupEventListener (event) {
            var key = event.keyCode;

            switch (key) {
                case keys.left:
                case keys.right:
                    determineOrientation(event);
                    break;
                case keys.delete:
                    determineDeletable(event);
                    break;
            };
        };

        // Cuando la orientación de la lista de tabs se establece en vertical,
        // solo deberían funcionar las flechas hacia arriba y hacia abajo.
        // En todos los demás casos, solo la flecha izquierda y derecha funcionan.
        function determineOrientation (event) {
            var key = event.keyCode;
            var vertical = tablist.getAttribute('aria-orientation') == 'vertical';
            var proceed = false;

            if (vertical) {
                if (key === keys.up || key === keys.down) {
                    event.preventDefault();
                    proceed = true;
                };
            }
            else {
                if (key === keys.left || key === keys.right) {
                    proceed = true;
                };
            };

            if (proceed) {
                switchTabOnArrowPress(event);
            };
        };

        // Enfoca la tab siguiente, anterior, primera o última
        // dependiendo de la tecla presionada
        function switchTabOnArrowPress (event) {
            var pressed = event.keyCode;

            for (x = 0; x < tabs.length; x++) {
                tabs[x].addEventListener('focus', focusEventHandler);
            };

            if (direction[pressed]) {
                var target = event.target;
                if (target.index !== undefined) {
                    if (tabs[target.index + direction[pressed]]) {
                        tabs[target.index + direction[pressed]].focus();
                    }
                    else if (pressed === keys.left || pressed === keys.up) {
                        focusLastTab();
                    }
                    else if (pressed === keys.right || pressed == keys.down) {
                        focusFirstTab();
                    };
                };
            };
        };

        // Activa cualquier panel de tabs dado
        function activateTab (tab, setFocus) {
            setFocus = setFocus || true;
            // Desactivar el resto de tabs
            deactivateTabs();

            // Eliminar atributo tabindex
            tab.removeAttribute('tabindex');

            // Establecer la tab como seleccionada
            tab.setAttribute('aria-selected', 'true');

            // Obtener valor de los controles aria (es el id)
            var controls = tab.getAttribute('aria-controls');

            // Eliminar el atributo oculto del panel de tabs para hacerlo visible
            document.getElementById(controls).removeAttribute('hidden');

            // Establecer foco cuando sea necesario
            if (setFocus) {
                tab.focus();
            };
        };

        // Desactivar todas las tabs y sus respectivos paneles
        function deactivateTabs () {
            for (t = 0; t < tabs.length; t++) {
                tabs[t].setAttribute('tabindex', '-1');
                tabs[t].setAttribute('aria-selected', 'false');
                tabs[t].removeEventListener('focus', focusEventHandler);
            };

            for (p = 0; p < panels.length; p++) {
                panels[p].setAttribute('hidden', 'hidden');
            };
        };

        function focusFirstTab () {
            tabs[0].focus();
        };

        function focusLastTab () {
            tabs[tabs.length - 1].focus();
        };

        // Detectar si una tab se puede borrar
        function determineDeletable (event) {
            target = event.target;

            if (target.getAttribute('data-deletable') !== null) {
                // Eliminar tab target
                deleteTab(event, target);

                // Actualizar arrays relacionados con widget de pestañas
                generateArrays();

                // Activar la tab siquiente a la que se acaba de eliminar
                if (target.index - 1 < 0) {
                    activateTab(tabs[0]);
                }
                else {
                    activateTab(tabs[target.index - 1]);
                };
            };
        };

        // Elimina una tab y su panel
        function deleteTab (event) {
            var target = event.target;
            var panel = document.getElementById(target.getAttribute('aria-controls'));

            target.parentElement.removeChild(target);
            panel.parentElement.removeChild(panel);
        };

        // Determinar si hay un retraso
        // cuando se navega con flechas de teclado
        function determineDelay () {
            var hasDelay = tablist.hasAttribute('data-delay');
            var delay = 0;

            if (hasDelay) {
                var delayValue = tablist.getAttribute('data-delay');
                if (delayValue) {
                    delay = delayValue;
                }
                else {
                    // Si no hay ningún valor especificado, por defecto 300ms
                    delay = 300;
                };
            };

            return delay;
        };

        function focusEventHandler (event) {
            var target = event.target;

            setTimeout(checkTabFocus, delay, target);
        };

        function checkTabFocus (target) {
            focused = document.activeElement;

            if (target === focused) {
                activateTab(target, false);
            };
        };
    }());

如果我添加了更多标签页,您可以独立导航吗,也就是说,不要停用这些标签页和其他模块的对应图像,是否可以轻松地做到这一点?

0 个答案:

没有答案