2015-11-05 21 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

相關問題