jQuery搞清楚父母是否已经失去了"焦点"

DA.*_*DA. 6 jquery children blur

我坚持找出使下拉菜单键盘可访问的逻辑.

HTML的结构如此(为了清晰起见,使用额外的类名称):

<ul>
    <li class="primaryMenuItem">
        <a href="">Link 1</a>
        <ul class="popUpMenu">
            <li><a href="">Sub Link 1</a></li>
            <li><a href="">Sub Link 2</a></li>
        </ul>
    </li>
    <li class="primaryMenuItem">
        <a href="">Link 2</a>
        <ul class="popUpMenu">
            <li><a href="">Sub Link 1</a></li>
            <li><a href="">Sub Link 2</a></li>
        </ul>
    </li>    
</ul>
Run Code Online (Sandbox Code Playgroud)

链接1和链接2,当悬停时,将显示子菜单列表(下拉菜单).我有一些jQuery和jQuery hoverIntent插件可以正常工作.

问题是这只适用于鼠标.

接下来的挑战是通过键盘使其工作.

我可以轻松地将焦点事件添加到顶级链接,然后触发辅助菜单:

$('ul.primaryMenuItem a:first').focus([call showMenu function]) 
Run Code Online (Sandbox Code Playgroud)

这很好.

要关闭菜单,一个选项是,当打开另一个菜单时,检查是否已经打开另一个菜单,如果是,请关闭它.

这也很好.

但是,如果你打开了最后一个菜单,那么它就会失败.由于您没有标记到另一个菜单,这个菜单保持打开状态.

挑战在于弄清楚如何/何时关闭菜单以及需要的逻辑(jQuery)来弄清楚它.理想情况下,当焦点位于页面上的元素上时,我会关闭菜单,而不是任何菜单的子元素.

从逻辑上讲,我正在寻找这个:

$('li.primaryMenuItem').blur([close $(this).find('ul.popUpMenu'))
Run Code Online (Sandbox Code Playgroud)

但是,您不能这样做,因为LI实际上没有焦点,而是其中的锚标记.

有什么建议?

更新:

也许是一个更好/更简单的方式来提问:

通过jQuery,有没有办法'观察'看焦点是否移动到特定对象的所有孩子之外?

emm*_*han 6

您可以使用事件冒泡来检查焦点在focusin事件上的内容.我使用以下代码取得了成功:


$("li:has(ul.popUpMenu)").focusin(function(e) {
    $(this).children().fadeIn('slow');
  });
  $('body').focusin(function(e) {
    if (!$(e.target).parent().is('ul.popUpMenu li')) {
      $('ul.popUpMenu').fadeOut('slow');
    }
  });

Run Code Online (Sandbox Code Playgroud)

你可以(应该)使它更优化,但它的工作原理.

  • focusin不会在某些浏览器中为body标签(或许多其他标签)触发.将tabindex设置为-1似乎可以解决这个问题并使这个解决方案更合适 - $("body").attr("tabindex", - 1); (2认同)

Kel*_*tex 2

使用新的 jquery 1.4 函数:focusinandfocusout代替blurand focus。以下是focusout不同之处:

当某个元素或其内部的任何元素失去焦点时,将向该元素发送 focusout 事件。这与模糊事件不同,因为它支持检测父元素失去焦点(换句话说,它支持事件冒泡)。