2016-01-21 90 views
0

我目前使用这个脚本在一个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); 
    }); 
} 

}); 

不过,我需要这些物品是键盘访问。

任何人都可以指向正确的方向吗?

谢谢!

回答

0

这个问题的答案是使用的focusIn和事件的内容处理程序:

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

您正在尝试以实施像一个Chimera的用户界面模式。你有一个单一的元素(顶级菜单项),试图成为一个链接和一个菜单项(与子菜单)。使这种用户体验易于使用并且易于使用是非常困难的。

如果您采用@ tom-usborne建议的操作,只需打开focusinfocusout上的菜单,那么仅键盘用户将不得不通过所有下拉菜单中的每个菜单项进行选项卡选项卡。想象一下,史蒂文霍金不得不使用他的脸颊肌肉多次按下tab键!不太好用。

另一种方法 - 比如实施ARIA authoring guidelines for menu interaction意味着顶级项目的链接根本无法访问(因为回车键会打开菜单而不是点击链接)。

但是,如果你只是实现ARIA模式,那么你会发现在iOS上,菜单不能与之交互。我推荐一种混合方式,将顶层链接移动到菜单中,使用正常的单击(或触摸或鼠标悬停)将菜单切换为打开和关闭,然后打开后,可以通过菜单中的所有链接进行选项卡。这种方法在所有设备上都能正常工作。