Set JAWS cursor focus programmatically - javascript

I'm developing a web application that needs to be accessible via JAWS. There is a requirement which says that newly opened dialogs need to be focused on in order to be announced by JAWS. I implemented this, and it's working fine without JAWS: the dialog's first element has focus. Testing this web site with JAWS+IE shows that the element is focused, but the braille viewer shows something different (part of the page header) and that's also being read.
From my understanding, this means that the PC's cursor is correct, but the JAWS cursor is misplaced.
Is there any way to influence the JAWS cursor placement using JavaScript?

When testing with JAWS, you need to not just look at the screen but listen to what JAWS is saying. Spend time getting to know JAWS intimately if you need your testing to provide reliable results.
The best way to create an accessible dialog is to:
Ensure the dialog heading has an ID attribute.
If the dialog has a short message, make sure this also has an ID attribute.
Give the container a role of "dialog" and a tabindex of "-1".
Ensure that the container's ARIA-LABELLEDBY attribute contains the ID of the heading.
Ensure the container's ARIA-DESCRIBEDBY attribute contains the ID of the short message if there is one.
When the dialog opens, send focus to the container.
If you follow this pattern to the letter, your dialog will work beautifully with JAWS and other AT.
Simple example:
<div id="dlg_discard" tabindex="-1" role="dialog" aria-labelledby="dialog_heading" aria-describedby="dialog_message">
<h1 id="dialog_heading">Discard changes?</h1>
<p id="dialog_message">Are you sure you want to discard your changes?</p>
<button>Yes</button> <button>No</button>
</div>
... And the jQuery to make the dialog visible ...
$("#dlg_discard").show().focus();

Is there any way to influence he JAWS cursor placement (via Javascript)?
No

Related

Screen reader aria live assertive text is interrupted

$('#firstButton').focus();
<div id="liveRegion" aria-live="assertive">
This is a very long text
</div>
<button id="firstButton">First Button</button>
I am quite a newbie in accessibility issues. I basically have a button on which I want the focus to be on page load, but I also want a text to be picked up by the screenreaders in the liveRegion.
Right now, the text will be inteerrupted at some point during page load, and focus goes to the button.
Is there a way to have the screenreader not be interrupted?
Live regions can be confusing at first. The purpose of a live region is to announce changes to the page, not to announce page load information. After your page is loaded, if something changes on the page, such as the text within an element, or a new element is added, those changes can be announced if the aria-live attribute is used.
Most pages do not announce anything as they're loaded. A screen reader user will hear that the page is loading, and when it's done (usually there's an audible clue in the screen reader to let you know if the page is still loading or if it's done), the page title is typically announced and then whatever object has initial focus is read.
If you really need something read after the page loads, then it should probably have the initial focus. But be careful because putting focus on a non-interactive element such as a paragraph (<p>) or non-semantic elment (<div>) can be confusing. If you have to resort to that, make sure that element has tabindex="-1" so that the element will not be in normal keyboard focus order.
as such, there is no way to prevent the reading of your text by the button gaining focus.
The order of priority of what to say when heavily depends on screen reader / browser / OS combination, but usually, an element taking the focus has priority against any live region, including assertive.
What you can do is making the live region assertive text appear after the focus is moved to the button.
It has greater chances to be announced without interruption then.
IN any case, a live region present at page load isn't reliably read on all platforms.
To make sure that it will be effectively spoken, make it appear in the DOM after the page has completely finished to load.

Hide all elements from screen readers except one div?

I have implemented a popup that is triggered from a button on my webpage. This popup nearly fills the entire screen and prevents users from interacting with anything on the webpage until the popup is dismissed. This works well for sighted users, but when using VoiceOver on the Mac you can still navigate the underlying web page content, and the blind user would have no idea a popup window was presented.
How can I prevent VoiceOver from navigating every element on the page except for one div (and every element in that div)?
I know one can use aria-hidden="true" to hide it from screen readers, and I know one can force a focus on an element, but I'm not sure how best to accomplish this. Do I need to loop over the entire DOM and essentially hide everything then upon close unhide everything? Or is there a better approach, some ARIA property that defines this type of element that's presented perhaps?
A website that exhibits the desired behavior is Piazza. When you activate the Login button it presents a popup modal dialog and demands focus, and you can't navigate away from it until you dismiss the popup.
Implementing accessible modal dialogs correctly has got to be one of the trickier aspects of web accessibility, since there's just so many things to watch out for, on top of the usual issues of screenreader and browser compat and adherence to spec. Here's a summary(!), somewhat based on personal experience, this article from Smashing Magazine on accessible Modal dialogs, WAI-ARIA 1.0 Authoring Best Practices and this slideshow on the same topic.
(Note that you'll find some conflicting advice between these; this is somewhat due to differences in behavior between screenreaders/browsers and spec, and different authors having different positions on whether to stick to spec vs work with the screenreaders that real users actually use.)
Tell screenreaders it's a dialog: Add role="dialog" to the parent DIV, and set aria-labelledby to point to the ID of the title.
This causes the screenreader to recognize the piece of UI as a dialog in the first place; when the user navigates into it, either by navigating or because focus moves into it, the screenreader will announce that the user is now in a dialog, and will likely also announce the title. (On some screenreader/browser combinations - notably VoiceOver+Safari, it may also affect how screenreader navigation works.) This alone does not 'hide' any of the other UI on the page, however.
Add basic keyboard support
There's a bunch of things to do here that are important for both screenreader users and non-screenreader using keyboard users. Two key issues here are to move focus to somewhere appropriate in the the dialog when it initially appears, and when the dialog is dismissed, restore focus back to where it was when the dialog originally appeared.
Make it modal for screenreader users and keyboard users
Dialogs come in two flavors: modal, which don't let the user interact with any other UI while present, and modeless, which do let the user leave the dialog and return later - examples might be the "Find Text" dialogs in some text editors. role="dialog" doesn't distinguish between these two cases, and also using ARIA doesn't have any affect on browser behavior, so if your dialog is modal, you have to do extra work yourself to make it behave as modal. There's two aspects to this:
Just as modal dialogs use a gray scrim or blur effect to visually hide the inactive background from sighted users, we also want to hide this content from screenreader users: otherwise they will still be able to navigate out of the dialog to the background, or use other hotkeys to list links or headings or other controls from the page and will see both items from the background part of the page and the dialog. In the past, putting aria-hidden="true" on all other top-level DIVs was the best tool to use to do this (and a bit fiddly - remember to remove it when done!), but as of 2020, aria-modal="true" appears to be decently supported and is much easier to implement.
For both screenreader users and non-screenreader-using keyboard users, you also need to make the keyboard behavior modal: hitting tab from the last item in the dialog should wrap to the top of the dialog, and the inverse behavior for shift-tab. If you don't do this, keyboard - and screenreader - users can simply tab right out of your dialog into the background of the page. There's different approaches for doing this, most involve tracking focusin or similar at the body level, and forcing focus back into the dialog if it "escapes".
Other tweaks/fixes/hacks
Windows-based screenreaders such as NVDA and JAWS go into "application mode" when they enter a dialog: their web navigation hotkeys no longer work, and they treat the content of the dialog as a form rather than a rich web page. This is fine is the dialog content is a classic form with just fields, labels and buttons, but isn't a good fit if the dialog contains web content with text, hyperlinks, and the like. In that case, you might want to place a <div role="document">...</div> within your role="dialog" but wrapping the main content.
Ensure dialog content is itself accessible
Should go without saying, but all of the above counts for nothing unless the content within the dialog is itself accessible.
Most importantly: understand why you are making the dialog accessible in the first place, and test appropriately.
Unfortunately, at the moment (Jan 2015!) there's still a lot of variation in behavior between different screenreaders (also depending in browser used); it's almost like how browsers were with CSS a decade(!) or so ago. It's worth understanding why you want to make your UI accessible, figure out where most of your users are going to be, and test appropriately given the screenreaders they'll be using. From the most recent (Jan 2014) WebAim Screenreader survey, Windows readers - notably JAWS and NVDA - have the majority of the market, with VoiceOver coming third.
Here's one possible strategy to consider:
If you just want to do a basic 'due diligence', then testing with just VoiceOver may be fine. The experience may not be as good on the other screenreaders, but if something works with VO, it's likely not going to be completely broken on the others.
Next level up is to get a copy of (free, but feel free to donate) NVDA windows-based screenreader and run it in a VM on a Mac (assuming you're using a Mac here). NVDA and JAWS tend to be pretty close behavior-wise.
If accessibility is part of your job description, then likely you or your company will need to get a copy of JAWS ($800+!), since that appears to be the screenreader of choice for government and educational institutions. (This is perhaps the accessibility analog of testing with downlevel versions of IE!)
You should iterate through all the top level items and set aria-hidden=true on those items. This is an example:
<!doctype html>
<html>
<head>
<title>aria-hidden examples</title>
</head>
<body>
<a aria-hidden="true" href="#">Link at top</a>
<p aria-hidden="true">Lots of text content</p>
<form aria-hidden="true">
<label for="input">Label</label>
<input id="input" type="text" />
<button>Submit</button>
</form>
<div>
<label for="dialogInput">Nother Label</label>
<input id="dialogInput" type="text"/>
</div>
<form aria-hidden="true">
<label for="input2">Label 2</label>
<input id="input2" type="text" />
<button>Submit 2</button>
</form>
<a aria-hidden="true" href="#">Link at bottom</a>
</body>
</html>
The problem is that this will cause the announcements to stay within the "dialog", but if you press the tab key, the focus can move outside the dialog and not get announced. This means that if there are interactive elements outside the dialog, the user could end up interacting with the wrong elements. Other browsers will do similar things.
So you will need to trap the focus inside the dialog using a Javascript event handler to handle your TAB keys if your page includes other naturally focusable elements like in the example above.
WAI-ARIA provides the dialog and alertdialog roles to define dialogs. The dialog role is used when the user is expected to provide data, and the alertdialog role is used to announce the contents of a dialog to the user.
Alert dialog
<div role="alertdialog"
aria-labelledby="dlgtitle"
aria-describedby="instructions">
<h1 id="dlgtitle">Shutdown instructions</h1>
<ol id="instructions">
<li>Open timesheet</li>
<li>Enter time for today</li>
<li>Close all open applications</li>
<li>Shut down system</li>
</ol>
<div>
<input type="button" value="OK">
</div>
</div>
Dialog
<div role="dialog" aria-labelledby="dlgtitle">
<h1 id="dlgtitle">Sign up to Newsletter</h1>
<ol id="instructions">
<li>Enter email address</li>
<li>Press the 'Sign up' button</li>
<li>You're all signed up!</li>
</ol>
<div>
<label for="email">Email: </label>
<input type="text"
id="email"
name="email"
aria-describedby="instructions">
<input type="button" value="Sign up">
</div>
</div>
WAI-ARIA Authoring practice design pattern for a modal dialog

Screen reader is not interpreting tab navgation?

I have a pop-up window that I have enabled with tab stops via tabindex=0. When I interact with the page without a screen reader, I can use the tab key to move between the window and form elements that it contains.
When I use my screen reader client (Window Eyes 8.4) to view my website, I cannot consistently tab into the window.
Are there any special cases with code structure that I should be considering that would cause the window to either lose focus or prevent the screen reader from interpreting the markup of the pop-up?
For reference - I'm in a ASP .NET MVC4 web app (page is HTML/CSS/JS) that is generating the pop-up with a Kendo UI [Kendo] Window.
03/17 Update -
The pop-up is intermittently announced by the screen reader as a dialogue box but as soon as the pop-up loads, I can - occasionally - tab into the div and focus is not lost. I am not able to consistently reproduce this and only found this out after pressing the tab key rapidly after pressing the button to show the pop-up.
On the other hand (when not hitting the tab key rapidly), the focus consistently lands at the pop-up without focus outlines (screen reader announces "Foo dialogue box") but on first tab keypress, focus jumps back to the underlying page at the last actionable element before the footer. Pressing tab at this time will then move me into the footer UL element.
It is difficult to answer without a demo, but there are a couple of areas to investigate.
I did a page on the accessibility requirements for a content based pop-up, i.e. one that is not a form. That also includes code on how to manage the focus.
If the pop-up is essentially form based, you might want to try this one on dialogue boxes.
You'll see from those examples that adding tabindex to the container is only part of it, you should manage the focus as well, so that the focus is moved to the pop-up.
The sporadic nature of the issue might be because screen readers generally don't read things that are display:none, and tabbing to something that isn't there may not activate reliably.
If you can post an example I can update this answer.

Does a browser perform selection of corresponding Javascript to screen elements?

Right Click, inspect element allows me to see corresponding html & css to screen element. Does the browser likewise, permit tracing the javascript function to corresponding clicks? Or do you manually need to trace from onclick event, so on and so forth?
If so, can one likewise, perform editing of the Javascript, in a browser to verify, what changes will it bring about? Much like, what we can do for html & css
On Google Chrome i discover, in Elements on the right side screen, one can browse to Event Listners then click event to see some Javascript. I'm still deciphering it to see if it permits simultaneous browser screen manipulation.
It doesn't seem to be working at the moment.

Making divs act like proper links

I'm using a JavaScript (jQuery) calendar where some calendar events act as links. The calendar events are divs that have onclick triggers that point the browser to the correct page.
The problem is that since the calendar event's aren't <a href=".."> links the user can't ctrl+click to open the link to a new tab or shift+click to open to a new window. I'm looking for a way to get this functionality to the calendar and it seems like my options are:
Detect whether the user has shift pressed and open to a new window or ctrl pressed and open to a new tab - I'd rather not do this because opening to a new tab will probably have to be coded separately for each browser (?) and it might override user's preferences.
Remove the onclick triggers and wrap the div content inside <a></a> that fills the entire enclosing div.
Hack the calendar library to use <a> tags instead of divs for clickable calendar events.
Is there by any chance any other method to tell the browser to consider divs as regular links? Are there any foreseeable side effects to methods #2 or #3?
I'd say your easiest/most complete solution would be to use anchors just as they are (e.g. no script required), just use CSS to do the work here, with display: block or display: inline-block and style them like <div> elements.
This way, all the native clicking behavior can be handled by the browser and the user's preferences as well as Ctrl, Shift, etc clicking is whatever the user is expecting it to do.
Find a calendar that uses proper markup, or fork the plugin and go for #3. The down side to the later is that since you're forking, you cut yourself off from upgrades

Categories