2015-11-05 38 views
1

我有一个简单的导航栏,我打算在所有键盘可访问导航上使用。导航栏是指像这样的工作:JQuery - 在Firefox和IE中通过Tab导航时焦点不工作

  • 使用标签键,你应该能够通过每个 导航类别及其元素进行导航。

  • 使用右*和**左键,您只能浏览导航类别。

  • 使用向下键还允许您打开导航类别。

  • 使用ESC键关闭(隐藏)当前可见的导航类别。

这是我开发的jsFiddle

为了简单起见,请关注JavaScript代码,因为HTML代码由于我的控制之外的需求原因而无法更改。我认为问题在于Firefox/IE如何处理focus事件与Chrome中的不同。

$(document).ready(function(){ 
    var utilitymenu = new menuBar("#utility-nav"), 
     navInner = new menuBar("#nav-inner"), 
     mainHeader = $(".main-header"); 

    // Adding tabindex to all clickable anchor links 
    mainHeader.find("a").each(function(i, elem){ 
     $(elem).attr("tabindex", i+1); 
    }); 
}); 

function menuBar(id){ 
    var linksBlock = id + " > li", 
     linksBlockSelector = " > li", 
     submenuHeader = linksBlock + " > a", 
     submenu = linksBlock + " div[class*='sub-menu']", 
     submenuSelector = "div[class*='sub-menu']", 
     textBlock = submenu + " > ul", 
     textBlockSelector = submenuSelector + " > ul", 
     submenuElem = textBlock + " > li a", 
     keepMenuClosed = false; 

    // Adding ARIA attributes to the different sections of the navigation menus 
    $(linksBlock).attr({ 
     "role": "navigation", 
     "aria-haspopup": "true", 
     "aria-labelledby": "menu-title", 
     "aria-describedby": "menu-description" 
    }); 
    $(submenuHeader).attr({ 
     "aria-haspopup": "true", 
     "id": "menu-title" 
    }); 
    $(submenuHeader).each(function(i, elem){ 
     $(elem).attr("aria-label", $(elem).text().trim()); 
    }); 
    $(submenu).attr({ 
     "tabindex": "-1", 
     "id": "menu-description" 
    }); 
    $(textBlock).attr({ 
     "aria-expanded": "false", 
     "aria-hidden": "true" 
    }); 

    // Hides visible menus when clicking outside the menu area 
    $(document).click(function(event) { 
     if(!$(event.target).closest().length){ 
      $(submenu + ":visible").hide().find(textBlock).attr("aria-expanded", "false"); 
      $(submenu + ":visible").hide().find(textBlock).attr("aria-hidden", "true"); 
     } 
    }); 

    // Drop Down Menu event handler (not inner elements) 
    $(linksBlock) 
    .focus(function(){ 
     if($(this).find(submenuSelector).is(":hidden") && !keepMenuClosed){ 
      $(this).find(submenuSelector).toggle(); 
      $(this).find(textBlockSelector).attr("aria-expanded", "true"); 
      $(this).find(textBlockSelector).attr("aria-hidden", "false"); 
      keepDropdownClosed = false; 
     } 
     else if($(this).find(submenuSelector).is(":visible")){ 
      $(this).find(submenuSelector).toggle(); 
      $(this).find(textBlockSelector).attr("aria-expanded", "false"); 
      $(this).find(textBlockSelector).attr("aria-hidden", "true"); 
     } 
    }) 
    .mouseover(function(){ 
     $(this).find(submenuSelector).show(); 
     $(this).find(textBlockSelector).attr("aria-expanded", "true"); 
     $(this).siblings().find(submenuSelector).hide(); 
     $(this).siblings().find(textBlockSelector).attr("aria-expanded", "false"); 
     $(this).find(textBlockSelector).attr("aria-hidden", "true"); 
    }) 
    .mouseout(function(){ 
     $(this).find(submenuSelector).hide(); 
     $(this).find(textBlockSelector).attr("aria-expanded", "false"); 
     $(this).find(textBlockSelector).attr("aria-hidden", "true"); 
    }) 
    .keydown(function(event){ 
     switch(event.keyCode){ 
      //tab key 
      case 9: 
       keepMenuClosed = true; 
       if($(this).find(submenuSelector).is(":visible")){ 
        $(this).find(submenuSelector).toggle(); 
        $(this).find(textBlockSelector).attr("aria-expanded", "false"); 
        $(this).find(textBlockSelector).attr("aria-hidden", "true"); 
       } 
       else if($(this).find(submenuSelector).is(":hidden")){ 
        $(this).find(submenuSelector).toggle(); 
        $(this).find(textBlockSelector).attr("aria-expanded", "true"); 
        $(this).find(textBlockSelector).attr("aria-hidden", "false"); 
       } 
       break; 

      // esc key 
      case 27: 
       if($(this).find(submenuSelector).is(":visible")){ 
        $(this).find(submenuSelector).toggle(); 
        $(this).find(textBlockSelector).attr("aria-expanded", "false"); 
        $(this).find(textBlockSelector).attr("aria-hidden", "true"); 
        $(this).closest(linksBlock).focus(); 
       } 
       break; 

      // key left 
      case 37: 
       if($(this).find(submenuSelector).is(":hidden")){ 
        $(this).prev().find(" > a").focus(); 
        keepMenuClosed = true; 
       } 
       break; 

      // key right 
      case 39: 
       if($(this).find(submenuSelector).is(":hidden")){ 
        $(this).next().find(" > a").focus(); 
        keepMenuClosed = true; 
       } 
       break; 

      // key up/down 
      case 38, 40: 
       event.preventDefault(); 
       $(this).find(submenuSelector).show(); 
       break; 
     } 
    }); 
    // Sub Menu Elements keyboard handler 
    $(submenuElem) 
    .keydown(function(event){ 
     switch(event.keyCode){ 
      // tab key 
      case 9: 
       $(this).parent().next().find("a").focus(); 
       break; 
      // esc key 
      case 27: 
       if($(this).closest(submenuSelector).is(":visible")){ 
        $(this).closest("div").siblings("a ").focus(); 
       } 
       break; 
      // key up 
      case 38: 
       event.preventDefault(); 
       $(this).parent().prev().find("a").focus(); 
       break; 
      // key down 
      case 40: 
       event.preventDefault(); 
       $(this).parent().next().find("a").focus(); 
       break; 
     } 
    }); 
} 

TLDR

所有我想要做的就是理解为什么导航只能在Chrome中,而不是在IE和Firefox。我在做什么错误/根本不在这里?我一直在浏览IE/FF focus,preventDefault的已知问题,但无济于事。我不认为我的ARIA代码导致了这个问题,但我准备好探索所有的建议!

编辑

@Adam的建议下,我加入了下面的代码,以显示我已经在Firefox/IE的问题:

$(this).keydown(function(e){ 
    if(e.keyCode === 9){ 
     alert($(':focus').toArray()); 
    } 
}); 

它显示的问题的根源。我目前正在修改我的代码以更好地区分我如何听我的键盘笔画;以及更好地展示我的元素何时聚焦于此。

回答

1

当你隐藏的元素,因此当你按下了一个submenuElem事件也被linksBlock

截获该特定原因tab关键losts焦点

,当您使用以下line

$(this).parent().next().find("a").focus(); 

它触发focus()事件,然后执行切换,这将隐藏子菜单。这里失去了重点。

$(linksBlock) 
.focus(function(){ 
    [...] 

    else if($(this).find(submenuSelector).is(":visible")){ 
    $(this).find(submenuSelector).toggle(); 

并在那之后,第二个事件被触发,其将显示隐藏的元素没有焦点组的主要模块:

$(linksBlock) 
.keydown(function(event){ 
    [...] 
      else if($(this).find(submenuSelector).is(":hidden")){ 
       $(this).find(submenuSelector).toggle(); 
+0

这是吹我的心一点点,我需要坐下来并分析它,因为即使我理解你在说什么,我不知道如何解决它 – AGE

+0

我想分开我如何处理操作,我缩小了算法,以便我只听取*菜单*,*菜单元素*,*子菜单*和*子菜单元素*单独。这应该真的有助于理清问题。 – AGE

相关问题