【问题标题】:Keyboard accessible drop down menu not iterating through sub menu键盘可访问的下拉菜单不遍历子菜单
【发布时间】:2017-04-13 17:20:17
【问题描述】:

我需要一些帮助来解决我的导航问题。当列表项使用选项卡按钮成为焦点时,我可以获得导航以显示下拉菜单,但我无法让选项卡遍历下拉菜单(子菜单),它只是选项卡到下一个列表项标记.

我尝试了 jQuery,但没有运气,现在我只是尝试使用 html、css 和 tabindex,但仍然没有运气。

HTML

    <nav aria-label="Main menu" id="globalNav" >
      <ul>
       <li class="dropdown" tabindex="0" ><a href="#"><span itemprop="name">Welcome</span></a>
        <ul class="sub-menu">
         <li role="menuitem"><a href="#">Visitor</a></li>
         <li role="menuitem"><a href="#">Aid</a></li>
         <li role="menuitem"><a href="#">Payments</a></li>
       </ul>
      </li>
     <li class="dropdown" tabindex="0"><a href="#"><span itemprop="name">Sports</span></a>
       <ul class="sub-menu">
        <li role="menuitem"><a href="#">Basketball</a></li>
        <li role="menuitem"><a href="#">Football</a></li>
        <li role="menuitem"><a href="#">Soccer</a></li>
      </ul>
     </li>
    </ul>
  </nav>

CSS

    #globalNav {
     width: 100%;
     border-bottom: 3px solid rgba(74, 61, 48, 0.3);
     padding: 0.54rem 0;
     margin-top: 30px;
     z-index: 10;
   }
   #globalNav ul {    
     list-style: none;
     display: table;
     margin: 0 auto;
     font-size: 1rem;
     text-transform: uppercase;
   }
   #globalNav ul li.dropdown {
     display: table-cell;
     padding: 0 10px;
     border-left: 1px solid #EEE;
     text-align: center;
   }

  #globalNav ul li.dropdown a{
    color: #4A3D30;
    display: inline-block;
    position: relative;
   }
    #globalNav ul li.dropdown a:hover,
    #globalNav ul li.dropdown a:focus,
    #globalNav ul li.dropdown a:active{
       color:#666;
    }

    #globalNav ul li.dropdown a.active:after{
      width: 100%;
      background: #990000;
    }

    #globalNav ul li.dropdown a:after{
      content: "";
      display: block;
      margin: auto;
      height: 2px;
      width: 0;
      background-color: transparent;
   }
  /*Children GlobalNav*/
   #globalNav ul li.dropdown a ul.sub-menu {
   }

    #globalNav ul li.dropdown  ul.sub-menu {
      position: absolute;
      display: none;
      z-index: 100;
      text-transform: none;
      min-width: 256px;
      max-width: 256px;
   }

    #globalNav ul li.dropdown:hover  ul.sub-menu,
    #globalNav ul li.dropdown:focus ul.sub-menu,
    #globalNav ul li.dropdown:active ul.sub-menu{
     display: block;
     background-color: #dcd8d6;
     color: #4a3d30;
   }
    #globalNav ul li.dropdown ul.sub-menu:hover,
    #globalNav ul li.dropdown ul.sub-menu:focus,
    #globalNav ul li.dropdown ul.sub-menu:active {
      background-color: #3f79c1;
    }

   #globalNav ul li.dropdown ul.sub-menu li a {
    padding: 8px;
   }

这是我的代码笔 http://codepen.io/nicban/pen/vmEEPr

我觉得我错过了一些明显的东西

【问题讨论】:

    标签: html css accessibility


    【解决方案1】:

    我使用一些脚本为具有焦点的项目添加一个类,然后沿着 DOM 将其添加到祖先,以便我可以显示它们。当焦点改变时,我也会删除该类。

    自从我审查它以删除/调整任何愚蠢的位以来已经有一段时间了。

    您遇到的部分问题是您使用的是display: none,这意味着键盘永远找不到它。如果您使用屏幕外技术,则用户可以使用 Tab 键进入控件。

    另外,请删除整个role="menuitem" 以及tabindex="0"。前者意味着您不支持的交互(例如箭头键),而后者会创建额外的制表位,这些制表位不会正确地向屏幕阅读器显示。

        // Get the nav by id
        var pNav = document.getElementById("globalNav");
    
        function unClassy(){
          try {
            // Remove the focus class
            pNav.classList.remove("focus");
            // Remove the focus class from all its descendents
            pNavDesc = pNav.getElementsByTagName('*');
            for( var i = 0; i<pNavDesc.length; i++){
              pNavDesc[i].removeAttribute("class");
            }
          } catch (e) {
            console.log(e);
          } 
        }
    
        /* For any clicks, clear the focus class from the nav and all its descendants, essentially closing the menu when a user clicks/taps outside of it. */
        document.documentElement.onclick=function() {
          try {
            unClassy();
          } catch (e) {
            console.log(e);
          }
        }
    
        /* Manipulate focus classes in navigation. */
        function classy(){
          try {
            unClassy();
            // Add the focus class to items that have focus
            // Get the element that currently has focus
            var focusedElement = document.activeElement;
            // If that element is the primary nav, add the class
            if (focusedElement.id == pNav.id){
              // Add the focus class
              pNav.classList.add("focus");
            }
            // If nav contains the focused element, add the class
            if (pNav.contains(focusedElement)){
              focusedElement.classList.add("focus");
              el = focusedElement;
              while (el.parentNode) {
                el.classList.add("focus");
                el = el.parentNode;
              }
            }
          } catch (e) {
            console.log(e);
          }
        }
    
        /* Delay the assigning of classes to give the :focus a chance to catch up. There has to be a better way for this. */
        document.documentElement.addEventListener("keydown", delayClassy, false);
        function delayClassy(){
          try {
            setTimeout(classy, 200);
          } catch (e) {
            console.log(e);
          }
        }
    

    【讨论】:

    • 太棒了。你的例子对我有用。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多