键盘可访问导航

时间:2016-01-21 20:52:42

标签: wordpress navigation accessibility

我目前正在将此脚本用于WordPress主题中的下拉菜单项:http://jsfiddle.net/i_like_robots/6JbtX/

$(function()
{
var $dropdowns = $('li.dropdown'); // Specifying the element is faster for older browsers

/**
 * Mouse events
 *
 * @description Mimic hoverIntent plugin by waiting for the mouse to 'settle' within the target before triggering
 */
$dropdowns
    .on('mouseover', function() // Mouseenter (used with .hover()) does not trigger when user enters from outside document window
    {
        var $this = $(this);

        if ($this.prop('hoverTimeout'))
        {
            $this.prop('hoverTimeout', clearTimeout($this.prop('hoverTimeout')));
        }

        $this.prop('hoverIntent', setTimeout(function()
        {
            $this.addClass('hover');
        }, 250));
    })
    .on('mouseleave', function()
    {
        var $this = $(this);

        if ($this.prop('hoverIntent'))
        {
            $this.prop('hoverIntent', clearTimeout($this.prop('hoverIntent')));
        }

        $this.prop('hoverTimeout', setTimeout(function()
        {
            $this.removeClass('hover');
        }, 250));
    });

/**
 * Touch events
 *
 * @description Support click to open if we're dealing with a touchscreen
 */
if ('ontouchstart' in document.documentElement)
{
    $dropdowns.each(function()
    {
        var $this = $(this);

        this.addEventListener('touchstart', function(e)
        {
            if (e.touches.length === 1)
            {
                // Prevent touch events within dropdown bubbling down to document
                e.stopPropagation();

                // Toggle hover
                if (!$this.hasClass('hover'))
                {
                    // Prevent link on first touch
                    if (e.target === this || e.target.parentNode === this)
                    {
                        e.preventDefault();
                    }

                    // Hide other open dropdowns
                    $dropdowns.removeClass('hover');
                    $this.addClass('hover');

                    // Hide dropdown on touch outside
                    document.addEventListener('touchstart', closeDropdown = function(e)
                    {
                        e.stopPropagation();

                        $this.removeClass('hover');
                        document.removeEventListener('touchstart', closeDropdown);
                    });
                }
            }
        }, false);
    });
}

});

但是,我需要这些项目可以通过键盘访问。

有人能指出我正确的方向吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

您正在尝试实现类似Chimera的用户界面模式。您有一个单独的元素(顶级菜单项),它试图成为一个链接和一个菜单项(带有一个子菜单)。很难使用户体验易于使用且易于使用。

如果您执行@ tom-usborne建议的操作,只需打开focusinfocusout上的菜单,那么只有键盘的用户必须在每个菜单项中标记所有菜单项你的下拉菜单。想象一下Steven Hawking不得不使用他的脸颊肌肉多次按Tab键!不太好用。

替代方法 - 例如ARIA authoring guidelines for menu interaction的实现意味着根本无法访问顶级项目的链接(因为输入键将打开菜单而不是单击链接)。 / p>

但是,如果您只是实现ARIA模式,那么您会发现在iOS上,菜单无法与之交互。我建议使用混合,您可以将顶级链接移动到菜单中,允许使用正常点击(或触摸或鼠标悬停)切换菜单打开和关闭,然后一旦打开,您可以选中菜单中的所有链接。这种方法适用于所有设备。

答案 1 :(得分:0)

答案是使用focusin和focusout处理程序:

$dropdowns
.on('focusin', function() // Mouseenter (used with .hover()) does not trigger when user enters from outside document window
{
    var $this = $(this);

    if ($this.prop('hoverTimeout'))
    {
        $this.prop('hoverTimeout', clearTimeout($this.prop('hoverTimeout')));
    }

    $this.prop('hoverIntent', setTimeout(function()
    {
        $this.addClass('hover');
    }, 250));
})
.on('focusout', function()
{
    var $this = $(this);

    if ($this.prop('hoverIntent'))
    {
        $this.prop('hoverIntent', clearTimeout($this.prop('hoverIntent')));
    }

    $this.prop('hoverTimeout', setTimeout(function()
    {
        $this.removeClass('hover');
    }, 250));
});