javascript - Simulate Voiceover page load in single-page pushState web application -


i'm working on single-page application (spa) we're simulating multi-page application html 5 history.pushstate. looks fine visually, it's not behaving correctly in ios voiceover. (i assume wouldn't work in screen reader, voiceover i'm trying first.)

here's example of behavior i'm trying achieve. here 2 ordinary web pages:

1.html

<!doctype html><html> <body>this page 1. <a href=2.html>click here page 2.</a></body> </html> 

2.html

<!doctype html><html> <body>this page 2. <a href=1.html>click here page 1.</a></body> </html> 

nice , simple. voiceover reads this:

web page loaded. page 1.
[swipe right] click here page 2. link.
[double tap] web page loaded. page 2.
[swipe right] click here page 1. visited. link.
[double tap] web page loaded. page 1.

here again single-page application, using history manipulation simulate actual page loads.

spa1.html

<!doctype html><html> <body>this page 1. <a href='spa2.html'>click here page 2.</a></body> <script src="switchpage.js"></script> </html> 

spa2.html

<!doctype html><html> <body>this page 2. <a href='spa1.html'>click here page 1.</a></body> <script src="switchpage.js"></script> </html> 

switchpage.js

console.log("load"); attachhandler();  function attachhandler() {     document.queryselector('a').onclick = function(event) {         event.preventdefault();         history.pushstate(null, null, this.href);         drawpage();     } }  function drawpage() {     var page, otherpage;     // in real life, we'd ajax call here or     if (/spa1.html$/.test(window.location.pathname)) {         page = 1;         otherpage = 2;     } else {         page = 2;         otherpage = 1;     }     document.body.innerhtml = "this page " + page +         ".\n<a href='spa"+otherpage+".html'>click here page " +         otherpage + ".</a>";     attachhandler(); }  window.onpopstate = function() {     drawpage(); }; 

(note sample doesn't work filesystem; have load webserver.)

this spa example visually looks simple multi-page example, except page 2 "loads quicker" (because it's not loading @ all; it's happening in js).

but in voiceover, doesn't right thing.

web page loaded. page 1.
[swipe right] click here page 2. link.
[double tap] click here page 1. visited. link.
[the focus on link! swipe left] page 2.
[swipe right] click here page 1. visited. link.
[double tap] web page loaded. page 1.

the focus on link, when should @ top of page.

how tell voiceover whole page has updated , reader should resume reading top of page?

jorgen's answer, based on another stackoverflow thread got me on right track.

the actual fix not wrap entire page in <div tabindex=-1> instead create <span tabindex=-1> around first part ("this page n") , focus that.

function drawpage() {     var page, otherpage;     // in real life, we'd ajax call here or     if (/spa1.html$/.test(window.location.pathname)) {         page = 1;         otherpage = 2;     } else {         page = 2;         otherpage = 1;     }     document.body.innerhtml = '<span tabindex="-1" id="page' + page + '">this page ' + page +         '.</span>\n<a href="spa'+otherpage+'.html">click here page ' +         otherpage + '.</a>';      document.getelementbyid('page' + page).focus();     settimeout(function() {         document.getelementbyid('page' + page).blur();     }, 0);     attachhandler(); } 

note in example blur focus in timeout; otherwise, non-screen-reader browsers draw visible blue focus rectangle around span, not want. blurring focus doesn't affect focus of ios vo reader.


Comments

Popular posts from this blog

javascript - Slick Slider width recalculation -

jsf - PrimeFaces Datatable - What is f:facet actually doing? -

angular2 services - Angular 2 RC 4 Http post not firing -