Web Development - Screen Reader Blocks Keyboard Events - javascript

We hired an accessibility company (Acme) to evaluate our web pages. Our page has a group of buttons that can be clicked only one at a time, and among their requests are:
Prevent the Enter Key to click a button, instead, make Space Key do the click.
Make the Right Arrow key do the same as Tab Key (move to the next button).
Nothing extraordinary there. Just use javascript to intercept the KeyDown event, determine which type is pressed (Enter. Space, Right-Arrow), and do the appropriate action.
I got that working like a charm....Until I turned on the Screen Reader (NVDA) :-(
Then everything fell apart. NVDA blocks and overrides all the KeyDown events for all the keys except the Tab.
Anyone has idea on how to achieve what Acme is asking for with the Screen Reader turned on?

tl;dr:
Don't go against usual conventions, unless you have a very good reason.
Space and enter
Concerning space and enter, both will normally activate the currently focused control, whether a screen reader is running or not. For HTML controls such as buttons and other inputs, the keypress is converted into a click event. This is a general keyboard convention.
Unless you have a very very good reason, you shouldn't go against normal conventions, simply because that's what's expected by the user. If the user presses enter and nothing happens, he/she will more probably conclude that the site isn't working and quickly leave, instead of trying the spacebar or looking around if there isn't a note somewhere explaining this weird behavior.
Additionally, the user may be running another kind of assistive tool that simulates a keypress on enter based upon another event, for example winking eyes or blowing in a tube. Many assistive technologies behave like keyboards, even if they are not actually keyboards.
In this case, preventing Enter from working normally will just prevent those people from using your site.
If you are afraid of users pressing Enter at an unexpected moment, this is your problem, not user's problem.
If the form is incompletely or incorrectly filled, you should notify the user about it. If you want to avoid processing the same action twice, you should disable the button after it has been clicked on it or pressed enter after the first time, and again, show a clue to the user that something is processing in case it takes a while to complete.
Arrow keys
Several screen readers offer two different modes of behavior, depending on whether the content is operable or not.
When some screen readerd encounter non-operable content, it enters "browse mode" (aka. "document mode" or "scan mode") 'takes control' of the keyboard, offering shortcuts for "next heading", "next word", "jump to navigation" and so on. In this mode, your own keyboard and mouse event handlers will never be triggered.
This is the perfectly normal behavior of screen readers in browse mode and you shouldn't attempt to change it. Arrow keys allow to read the page like a document in a text processing program, for example.
Many keys behave differently when a screen reader is running in browse mode, because these keys are needed for navigation.
Conversely, when the screen reader is in forms mode (aka. focus mode or input mode), input events are not intercepted, and work as normal, arrow keys will behave as you specified in your script.
NVDA enters forms mode when an operable element (such as a button or a text input field) is in focus. In this mode, you can handle arrow key events. It is primarily the semantics of the element in focus which decides the mode of the screen reader.
There are particular keyboard operation idioms for complex UI widgets (such as menus or radio button groups), where it is the whole widget that gets focus with TAB, and then arrow keys are used to manipulate focus within that widget). You should aim to follow these idioms if possible.
But beware because if you nest your elements incorrectly - such as a list inside a button - the screen reader wont really know how to handle it, and this can make the page difficult to read and/or use.
For more information on browse vs. input mode of screen readers, you can make a search.

Related

How to prevent screen reader focus (not referring to keyboard focus) from leaving predefined area (e.g., modal)

I've been trying to figure out how to contain the screen reader focus within a certain area. When I say screen reader focus, I don't mean the default browser focus that one can move with tabbing/shift-tabbing. I predominantly implement accessibility while using Voiceover on Mac, and when you turn that on, a new focus box appears on the page and reads out the information that it is 'highlighting'.
At that point if you were to tab, both the browser and the screenreader focus move concurrently. Aside from tabbing to different focusable elements, you can also hold cmd + opt and keypress left and right to move the screen reader focus from element to element, regardless if one can tab to it. That's the focus that I'm trying to contain.
I've tried preventing cmd, opt, and arrow key key presses when the focus is on the last element that I want focusable, but the browser doesn't seem to recognize the screen reader focus. And I believe that the keyboard disabling wouldn't work with the screen reader anyways, as it seems to work independently of the browser.
I've also tried dynamically adding tabindex: -1 and aria-hidden: true to all other elements on the page when a modal appears. This works when you turn on Voiceover after the fact; the screen reader focus does in fact get trapped. However if the screen reader is on first, which likely will be the case in most user instances, the screen reader doesn't respect the dynamic change. It's like the screen reader takes a 'snapshot' of the accessibility state as the page loads, and it doesn't respect new changes to the DOM.
Anyone have any ideas?
You can't prevent key shortcuts of the screen reader from being used. They have priority over everything else. They aren't even caught by a keydown/up/press handler within your script.
Fortunately for us as screen reader users, this isn't an acceptable way to go.
As you also have observed, the browse cursor is effectively completely independant from the system focus.
The accessibility tree determines what is reachable when using the screen reader's browse cursor.
To temporarily restrict the elements seen by the browse cursor, you must use the aria-modal attribute.
Put it on the root element that should be reachable. Everything inside will stay reachable. Everything else outside will no longer be reachable as long as the attribute stays on the element.
Don't play with aria-hidden to produce the same effect. Some screen readers have issues with nested elements having an aria-hidden attribute.
For example, if an outer element has aria-hidden=true and an inner element has aria-hidden=false, Jaws won't show the inner element.
Restricting the browse cursor with aria-modal, as well as hidding elements with aria-hidden by the way, doesn't automatically imply that they can't be focused with the regular system focus (Tab/Shift+Tab).
You will therefore usually double the aria-modal restriction with a focus trap to prevent the system focus from going to a place where it isn't expected.
If you don't do it, you may create troubles for screen reader users (what should the screen reader do if the focus is currently on an element hidden from the accessibility tree ?).
This is a recurrent oversight.
The safest to make a focus trap is to catch tab on the last allowed element and shift+tab on the first, and resp. bring the focus back to the first or last allowed element.
It's much easier than setting all focusable elements to tabindex=-1 and then back to tabindex=0, and as far as I have tested, it works almost everywhere.

How do I simulate a keyboard enter button press in JavaScript/jquery that is not selector specific?

I need a real, keyboard press simulation.Not one that is only selector specific. I need a way to simulate an actual enter button press on the keyboard, in JavaScript. This way the enter press will work the same every where i decide to trigger it , hence making it an actual enter button on a keyboard, simulation. Please help :) (I am using this in imacros and recording wont cut it because it is specific and not universal)
For security reasons, browsers won't allow you to simply simulate the pressing of a key from a browser context. If this were possible, then a user could load a web page and the javascript on the web page could take over the keyboard and do nasty things to the computer.
For a more detailed explanation, as well as some alternatives, see this post.

Can a bot click a link that makes a modal window in javascript?

I have a form that launches in a modal window (fancybox to be exact) that loads a page that triggers an event in Google Analytics. I'm trying to keep bots from clicking it.
Since the fancybox uses jQuery to load the html page, can a bot reach the page and trigger the event? I'm trying to determine if the events are real.
I'm getting a difference between unique events and total events and trying to explain why there would be a discrepancy. Is the only way to explain it as genuine people clicking or could it be bots?
Yes, a bot can do that. There's many ways of creating bots, and different methods will make most bots undetectable unless you have some really complex checks in place. I believe reCaptcha has a tonne of checks for example, ranging from the movement of the mouse, the react time of the user, user agents and so on and so forth.
Bots can come in all shapes and forms, including some that might use Selenium to imitate a user using an actual browser, or they could even be written in a lower level and move the mouse and cause key presses on a system level.
What it comes down to is how much energy/time you're willing to expend to make it harder for bots to do their thing. I doubt you'll ever get 100% accuracy on stopping bots.
But yes, a bot can trigger a button press event, or even press the button directly like a normal user would

Safest way to break Flash focus?

The gist: What's the best way to escape a Flash object's focus on a webpage?
Context:
I have a hotkey listener (an AutoHotKey script) running in my tray. If the script detects the command Alt+Shift+F6 while I am clicked into a Flash object on a webpage, it activates and sends key combinations to Flash to pull certain data logs. After this process completes, I want to call up a JavaScript file on that same browser tab that requests additional information from the user - basically, a tiny UI with additional text fields available in a third-party bug tracker. To do this, I want to send a javascript: command to the address bar using Ctrl+L and having AutoHotKey paste in the full call to the JS file.
A visualization of a possible environment:
The problem:
I need the user to be clicked INTO Flash in order to pull the data logs. However, I need the user to be clicked OUT of Flash for Ctrl+L to actually work - Flash appears to eat all keystrokes at the browser-level when one of its objects has focus.
A possible solution: The easiest way to go about this would be to simulate clicking on the stage, which borders my Flash object on every side. This should work, but I must assume the stupidest possible user. Such a user would somehow limit their current browser window to only be as big as the Flash object (if not smaller), click into it, and attempt to use the hotkey. In this case...I have no idea where I should click, because it could be outside the browser. Further, I don't believe I can assume that all browser address bars are similar amounts of pixels south from the top of the window.
Additional complicating factors:
I want this to work for the user's default browser. (IE, Chrome, Firefox, Safari are my big targets.)
AHK does not provide any native DOM or COM hooks to anything except IE.
Ctrl+Tab and Alt+Tab shenanigans do not appear to work. That can get me to other tabs/windows, but returning to the tab/window with the Flash object still causes Flash to 'eat' further keyboard input.
While I'd be open to using another scripting language than AHK if it could overcome this Flash focus hurdle, I do not know how to create a keylistener that sits in the users tray until activated by a hotkey.
I have no access to the Flash object's code, and it contains no logic to interpret a key combination as a way to break focus or launch a script.
Would it be possible to use WinMaximize to maximize the size of the window? If you do that it should be easier to set up the script to avoid clicking outside the browser.
Perhaps look at ControlFocus and/or ControlSend (using the "edit1" control in IE and FF -- unfortunately, Chrome doesn't expose the "address bar" as a "control" this way but if you test for Chrome first, you can implement your "click outside the Flash box" method for that case).

JavaScript keypress function and JAWS

I have a client that is required to be ADA-compliant. We found an issue when using IE9 and the JAWS screen reader. We have a jQuery function set up to scroll to another element on the page when the user Tabs down to a button and hits Enter. Here is the function:
jQuery('#ball_i5nqtjcVVB0CxYBJICklS6w').keypress(function(event) {
if (event.keyCode == 13) {
jQuery("#headofcurve").focus();
scrollTo("form");
liveballTag('Learn More');
}
});
The problem is that when JAWS is running, hitting Enter doesn't do anything. I must hit Shift + Enter in order for it to scroll to the proper section and begin reading.
This is normal behavior. It happens because of the way how JAWS (and most other moder screen readers, btw) handles webpages and other HTML-like content.
When a user opens up a webpage, he/she observes it with a so-called virtual cursor. That means that all keyboard commands change their meanings on webpages. This is done for the sake of quick navigation. For example, if you press h, you move to the next heading; if you press b, you move to the next button, and so on.
In order to type in something, you should be in forms mode. To enter the forms mode, you should press Enter on a form element such as an edit field or a combo box.
This said, you can't expect that Enter would be processed as you're used to do it without JAWS running.
You have two solutions here:
Change the keystroke to scroll to your element from Enter to, say, Ctrl+Enter (I'd suggest choosing another one since Ctrl+Enter is used for sending messages in tons of messengers and other software alike).
Assigning the application ARIA role to a part of your page. If JAWS encounters the application role, it passes all the keyboard commands through to the webpage itself. But be extremely careful with this mode since it's suggested by W3 Consortium not to overuse this role.

Categories

Resources