Make JAWS read page title programmatically when loading new content - jaws-screen-reader

I've inherited a project that uses a lot of click-triggered JS to change page content instead of linking to different actual HTML pages. I'm being asked to make JAWS read the page title when this happens, as if a new page is being loaded.
From my observations and a bit of light testing, reading the page title (meaning the contents of the <title> tag) is standard behavior for JAWS when linking to a new, separate page (as in a foo.html file), but not what happens when a same-page link or button is clicked.
How can I cause JAWS to read a page's title after a link or button is clicked that changes the existing page's content in a way that seems like a new page to the user but is actually the same file under the hood?
For this question, please assume that refactoring what I have to use an actual new page instead of JS content replacement is not an option. And if something is wrong with my initial assumptions, please let me know that as well.

It sounds like you have a single page app (SPA). You can't force the <title> element itself to be read but if you also put the same text into an aria-live="polite" container (a visually hidden <div> or <span> (*)), it'll be read.
You still want to update the title, even if it's not read, because the screen reader user can use a shortcut key (INS+T with jaws) to read the page title. And when the user switches between the browser and another app and then back again, they'll hear the title, so it's still important to update the title.
There are some decent blogs regarding accessible SPAs:
Accessible page titles in a Single Page App talks specifically
about the page title in SPAs
Building Accessible Single Page
Apps talks about general principles but doesn't really have any
code examples
Single page applications, Angular.js and accessibility talks specifically about using angular but the concepts and code examples can be applied generically.
(*) Note, when visually hiding the aria-live region, don't use CSS display:none because that'll hide it from the screen reader too. Use a sr-only type class. See What is sr-only in Bootstrap 3?

There's good info in slugolicious's answer. The specific issue has a simpler solution, though: <title> elements can be ARIA-ified.
<title role="banner" aria-live="polite">Default title here</title>
in conjunction with
$(function() {
// existing logic here
$(title).html("New title here");
});
being called when the new content loads.

Related

Screen reader not reading text within header tag

I have a header tag that contains the title of the page. The Windows screen reader is not reading that text and i wanted to know if there is a way to do so by adding some aria items?
<section class="section">
<header class="section-title" ip-l10n="county_list">List of Countries</header>
</section>
Just to make sure we're talking about the same thing, there are headings and headers. Headings are <h1> through <h6> elements. Headers are typically used when describing tables and are the names at the top of the column, the column header or <th> tag.
You had mentioned that your header contained the "title of the page". The title of the page is normally contained in a heading, specifically an <h1> if it's the main title of the page. So I wasn't clear which term you were really asking about.
I know your example used the <header> element so I will limit my comments to just that element, but I did want to point out the aforementioned differences to make sure we're all talking about the same thing. Accessibility and aria tags are all about semantics so it's good to be clear about the semantics of your question.
The <header> element is a container for stuff that's usually at the top of your page. By default, it creates a banner landmark. A <header> usually contains a <nav> which is the main navigation for the site that is repeated on all pages. It might also contain the company logo as an image and serves as a link back to the home page. It might also have account info, or if a retail site, the shopping cart contents. So a <header> might have interactive and non-interactive things.
In your example code, you just have plain text in your header. That's not interactive so a screen reader user will not hear the text if they are using the tab key to navigate the site. They will hear the text if they navigate the DOM using the up/down arrow keys with the screen reader.
If instead, you really meant for your code to be a heading, and thus the <h1> tag, that is also static text that is not interactive so again, the screen reader user will not hear the text if they are using the tab key to navigate the site. However, they can hear the text if they use the screen reader H quicknav key (to navigate to a heading).
So if you want to clarify your question, I can update my answer.

Top level navigation from html link in code in Markup slice

I had seen a comments that Apache Superset was edited to allow user activation of top level navigation for links in a Markup slice (so clicking a link redirects the page instead of just the contents of the slice). Does anyone know how to enable this option?
You can use HTML coding in the mark-up.
It works

Dynamically change address in the URL bar

Okay, I have seem similar questions around Stack sites, yet some of them were asked as far back as four years ago, so given the recent developments in HTML, jQuery and PHP, I'm convinced there are new workarounds.
Suppose I have a domain www.mysite.co.uk, which has an ajax that, once triggered, clears the default on-load content #0, and replaces it with content #1.
(This content can also be accessed by going to www.mysite.co.uk/1)
Then a user may trigger another ajax that will clear content #1 and populate with content #2.
This is where I have a problem. Because clicking the Back button will not send the user back to content #1 (in fact if there is no history, the Back button is greyed out).
What I want to do, is when user triggers an ajax that populates the page with content #3, I also want it to change the URL bar to www.mysite.co.uk/3, so this way the same content will load when the page is refreshed, instead of going back to the default content #0.
Hope this makes sense.
I know that www.asana.com do it, but not sure how.
I'm already developing grey hair by trying to sort this out.
Edit: I've seen some examples where they do that by #anchoring, or with a ?get_variable, but I'd rather do it by changing the URL-proper, like Asana.com does it.
You're looking for JavaScript's pushState() method in the history API:
Manipulating the browser history
Note: you can check compatibility with browsers on Can I use...

swapping rails3 layout on the fly

I have am trying to dig into twitter bootstrap and rails3 sites that actually look and function well (new to it all). I have this feature I want where I have a twitter bootstrap navigation (specified in what I guess is the default application layout) that calls a _navigation.erb.html etc. This works great, but on that navigation i want a "Se Habla Espanol" or what not, where when the user clicks there, the navigation text all changes to spanish. i thought easiest would be have another _navigationespanol.erb.html or something that changes the navigation words all around and also when click (toggling into spanish mode) it sets all the text in the pages to spanish by anytime there is a text render or whatever a variable flag was set and is interrogated on page index render show or what have you and it renders spanish or english words...
So ideally click on see it all in spanish, it loads a new layout (my main question) that has the spanish navigation and messages and other twitter bootstrap stuff and it also sets a global var i can look at in other renders to see if im rendering english or spanish.
More than swapping layouts, it seems that you need to implement Internationalization (I18n). In such case you'll have to create an directory config/locales that holds a .yaml file for each of the language you're trying to have translation for, for instance:
# on a file called en.yml
en:
hello: "Hello world"
For a complete guide on how to go about it: Rails Internationalization (I18n) API

Should I load an entire html page with AJAX?

My designer thought it was a good idea to create a transition between different pages. Essentially only the content part will reload (header and footer stay intact), and only the content div should have a transitional effect (fade or some sort). To create this sort of effect isn't really the problem, to make google (analytics) happy is...
Solutions I didn't like and why;
Load only the content div with ajax: google won't see any content, meaning the site will never be found, or only the parts which are retrieved by ajax, which arent't full pages at all
show the transitional effect, then after that 'redirect' the user to the designated page (capture the click event of a elements): effect is pretty much the same as just linking to another page, eg. user will still see a page being reloaded
I thought of one possible solution:
When a visitor clicks a link, capture the event, load the target with ajax, show the transitional effect in the meantime, then just rewrite the entire document with the content fetched with the ajax request.
At least this will work and has some advantages; the page reload will look seamless, no matter how slow your internet connection is, google won't really mind because the ajax content is a full html page itself, and can be crawled as is, even non-javascript browsers (mobile phones et al.) won't mind, they just reload the page.
My hesitation to implement this method is that i would reload an entire page using ajax. I'm wondering if this is what ajax is meant to do, if it would slow things down. Most of all, is there a better solution, eg. my first 'bad' solution but slightly different so google would like it (analytics too)?
Thanks for your thoughts on this!
Short answer: I would not recommend loading an entire page in this manner.
Long answer: Not recommended. whilst possible, this is not really the intent of XHR/Ajax. Essentially what you're doing is replicating the native behaviour of the browser. Some of the problems you'll encounter:
Support for the Back/Forward
button. You'll need a URI # scheme
to solve.
The Browser must parse
the entire page through AJAX.
This'll slow things down. E.g. if
you load a block of HTML into the
browser, then replace the DOM with
it, only then will any scripts, CSS
or images contained therein begin
downloading.
Memory - the
browser's not changing pages. Over
time (depending on the browser), I'd
expect the memory usage to increase.
Accessibility. Screen readers
will need to be notified whenever
the page content is updated. Might
not be a concern for you but worth
mentioning.
Caching. Browser
would not know which page to cache
(beyond the initial load).
Separation of concerns - your View
is essentially broken into
server-side pieces to render the
page's content along with the static
HTML for the page framework and
lastly the JS to combined the server
piece with the browser piece.
This'll make maintenance over time
problematic and complex.
Integration with other components -
you're already seeing problems with
Google Analytics. You may encounter
issues with other components related
to the timing of when the DOM is
constructed.
Whether it's worth it for the page transition effect is your call but I hope I've answered your question.
you can have AJAX and SEO: Google's proposal .
i think you can learn something from Gmail's design.
This may be a bit strange, but I have an idea for this.
Prepare your pages to load with an 'ifarme' GET parameter.
When there is 'iframe' load it with some javascript to trigger the parent show_iframe_content()
When there is no 'iframe' just load the page, with a hidden iframe element called 'preloader'
Your goal is to make sure every of your links are opened in the 'preloader' with an additional 'iframe' get parameter, and when the loading of the iframe finishes, and it calls the show_iframe_content() you copy the content to your parent page.
Like this: Link clicked -> transition to loading phase -> iframe loaded -> show_iframe_content() called -> iframe content copied back to parent -> transition back to normal phase
The whole thing is good since, if a crawler visit ary of your pages, it will do it without the 'iframe' get parameter, so it can go through all your pages like normal, but when you use it in a browser, you make your links do the magic above.
This is just a sketch of it, but I'm sure it can be made right.
EDIT: Actually you can do it with simple ajax, without iframe, the thing is you have to modify the page after it has been loaded in the browser, to load the linked content with ajax. Also crawlers should see the links.
Example script:
$.fn.initLinks = function() {
$("a",this).click(function() {
var url = $(this).attr("href");
// transition to loading phase ...
// Ajax post parameter tells the site lo load only the content without header/footer
$.post(href,"ajax=1",function(data) {
$("#content").html(data).initLinks();
// transition to normal phase ...
});
return false;
});
};
$(function() {
$("body").initLinks();
});
Google analytics can track javascript events as if they are pageviews- check here for implementation:
http://www.google.com/support/googleanalytics/bin/answer.py?hl=en-GB&answer=55521

Resources