javascripthtmlaccessibilityjaws-screen-reader

How to change the default JAWS reads for menu and menuitem roles to customized one?


I am creating the horizontal menu items with div tags by adding roles as menu and menuitem.

<div class="ul" role="menu">
  <div tabindex="0" class="li" role="menuitem"><a href="#home">Home</a></div>
  <div tabindex="-1" class="li" role="menuitem"><a href="#news">News</a></div>
  <div tabindex="-1" class="li" role="menuitem"><a href="#contact">Contact</a></div>
  <div tabindex="-1" class="li" role="menuitem"><a href="#about">About</a></div>
</div>

like this above code i am creating. I am styling this as horizontal navigation and binding events to do this(left and right arrows)

const btns = document.querySelectorAll(".li")
console.log(btns)
btns.forEach(btn => {
   btn.addEventListener('keydown', event => {
      if (event.keyCode == 39)
      document.activeElement.nextElementSibling.focus() 
      else if (event.keyCode == 37) document.activeElement.previousElementSibling.focus()
   });

}); 

but when jaws reading, its reading like use up and arrow button to navigate. how can i change this? in my case it should read like use left and right arrow buttons to navigate.

below is plunker https://plnkr.co/edit/rVOGMFHoWFt7F3Aicipz?p=preview


Solution

  • The short answer is you can't. When you specify a role, that's a clue to the screen reader (SR) that the object is going to behave a certain way. When the SR sees menu, it's going to announce that you can use up/down arrow keys to navigate, similar to how it will say "press spacebar to activate" when it sees role="button".

    However, a regular SR user is going to understand that when they hear "menu", they know they'll either be using up/down or left/right to navigate the menu and will, in general, ignore how the SR told them to interact. In fact, experienced SR users will probably change their verbosity to "low" so that the interaction phrase ("use up/down arrow" or "press spacebar") will not be announced at all.

    As long as you are following the "keyboard interaction" pattern for menus, you should be ok.

    Now, having said that, you might be able to use the (somewhat) new aria-roledescription attribute, but I'm not sure how well supported it is in all browsers and screen reader combinations. Setting its value might just affect the announcement of "menu" and not change the "use arrow keys" message. You'd have to do some testing.

    Note that your original example is a little weird. You essentially have two tab stops for each menu item. One for the <div> (because it has a tabindex="0") and one for the link. There's not really any need for the inner <div> elements. Just have something like:

    <div class="ul" role="menu">
      <a role="menuitem" href="#home">Home</a>
      <a role="menuitem" href="#news">News</a>
      <a role="menuitem" href="#contact">Contact</a>
      <a role="menuitem" href="#about">About</a>
    </div>