1
votes

I'm make an accessible website menu and would like to differentiate between a mouse "Click" and a VoiceOver "Press" to open a submenu. When I console.log the event the mouse event gets triggered on the VoiceOver "Press" instead of a keyboard event.

Is there a way to tell the difference?

Currently the menu is mouse hover based and I have prevented Click events from toggling the sub menu. I would however like keyboard only users to be able to open the submenus with screen readers which instruct the user to use command + option + spacebar for a PRESS which triggers a mouse event "click"...

One solution I'm working on now is to only disable click events when hover is active...

Update:

Goal: To trigger a mega menu popup for people who can see and link to a page displaying the mega menu links for people who cant. From my research, mega menus, even if coded beautifully are a pain for the visually impaired. Recognizing that a menu has expanding is not intuitive even if aria can tell that the menu item is expandable is does not seem to notify when it is expanded. I thought it would be a better experience for the user navigate to a new page and skip to the content of mega menu links.

Solution: I was able to successfully and independently target keyboard ENTER clicks VoiceOver/screenreader clicks and mouse clicks by using a collection of event listeners.

On mousein to the menu item I set a preventClick flag and on mouseout I remove the flag so that clicking the menu item did not follow the link and only opened the submenu.

On keydown I check if the "enter" key was pressed. If so I show the submenu and prevent the link from being the followed so that user and tab through the mega menu items.

That leaves the screen reader click to follow the link to page dedicated to showing the mega submenu.

Alternatively, for screenreaders, I could open the submenu and send the keyboard focus to the first element of the submenu. Not sure if this would be more intuitive for the user.

Review: Let me know if you think there are problems with this solution. So far it works great. It assumes that people motor control issues and good eyesight use tab+enter to navigate and people who are visually impaired use their screenreaders click equivalent eg. VoiceOvers Command+Option+Space.

2

2 Answers

2
votes

You will notice from this blog post that it is not possible to naiively differentiate between a mouse user and a screen reader user

http://unobfuscated.blogspot.com/2013/05/event-handlers-and-screen-readers.html

Even if it was possible, attempting to do so is considered a violation of privacy because it is tantamount to the user identifying themselves as disabled. There should not be any reason to want to do this - what is your use case?

Update

Your solution will work everywhere except touch devices, where hover does not exist, however that being said, you are going to too much trouble. As long as you mark up the mega menu semantically, the blind user will have no problem navigating it.

Take a look at https://www.capitalone.com/ for a reasonably accessible mega-menu implementation.

-1
votes

Your best shot is to override accessibilityPerformAction on the menu item, handle the NSAccessibilityPressAction, and then pass to super's implementation to handle things as it would as usual without you overriding anything. I haven't tried this yet, but I think it has a good chance of working. The point is accessibilityPerformAction gets invoked by VoiceOver (more specifically by AppKit's accessibility support on request from VoiceOver), so this way you know that some assistive technology (e.g. VoiceOver) requested opening the menu, not mouse.

Out of curiosity, I am still wondering why you want to differentiate between the 2 cases, what different behavior you would like to achieve.