Make revealJS screen reader friendly by announcing the contents of each slide presented

This commit is contained in:
Nawaz 2014-03-27 16:39:27 +05:30
parent 9da952fea3
commit 20a725222b
2 changed files with 37 additions and 3 deletions

View file

@ -386,6 +386,8 @@ var Reveal = (function(){
// Cache references to elements // Cache references to elements
dom.controls = document.querySelector( '.reveal .controls' ); dom.controls = document.querySelector( '.reveal .controls' );
dom.wrapper.setAttribute( 'role','application' );
// There can be multiple instances of controls throughout the page // There can be multiple instances of controls throughout the page
dom.controlsLeft = toArray( document.querySelectorAll( '.navigate-left' ) ); dom.controlsLeft = toArray( document.querySelectorAll( '.navigate-left' ) );
dom.controlsRight = toArray( document.querySelectorAll( '.navigate-right' ) ); dom.controlsRight = toArray( document.querySelectorAll( '.navigate-right' ) );
@ -394,6 +396,31 @@ var Reveal = (function(){
dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) ); dom.controlsPrev = toArray( document.querySelectorAll( '.navigate-prev' ) );
dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) ); dom.controlsNext = toArray( document.querySelectorAll( '.navigate-next' ) );
dom.statusDiv = createStatusDiv();
}
/**
* Creates a hidden div with role aria-live to announce the current slide content
* Hide the div off-screen to make it available only to Assistive Technologies
*/
function createStatusDiv() {
var statusDiv = document.getElementById( 'statusDiv' );
if( !statusDiv ){
statusDiv = document.createElement( 'div' );
var statusStyle = statusDiv.style;
statusStyle.position = "absolute";
statusStyle.height = "1px";
statusStyle.width = "1px";
statusStyle.overflow ="hidden";
statusStyle.clip = "rect( 1px, 1px, 1px, 1px )";
statusDiv.setAttribute( 'id', 'statusDiv' );
statusDiv.setAttribute( 'aria-live', 'polite' );
statusDiv.setAttribute( 'aria-atomic','true' );
dom.wrapper.appendChild( statusDiv );
}
return statusDiv;
} }
/** /**
@ -1544,6 +1571,7 @@ var Reveal = (function(){
// stacks // stacks
if( previousSlide ) { if( previousSlide ) {
previousSlide.classList.remove( 'present' ); previousSlide.classList.remove( 'present' );
previousSlide.setAttribute( 'aria-hidden', 'true' );
// Reset all slides upon navigate to home // Reset all slides upon navigate to home
// Issue: #285 // Issue: #285
@ -1628,6 +1656,7 @@ var Reveal = (function(){
verticalSlide.classList.remove( 'present' ); verticalSlide.classList.remove( 'present' );
verticalSlide.classList.remove( 'past' ); verticalSlide.classList.remove( 'past' );
verticalSlide.classList.add( 'future' ); verticalSlide.classList.add( 'future' );
verticalSlide.setAttribute( 'aria-hidden', 'true' );
} }
} ); } );
@ -1703,6 +1732,7 @@ var Reveal = (function(){
// http://www.w3.org/html/wg/drafts/html/master/editing.html#the-hidden-attribute // http://www.w3.org/html/wg/drafts/html/master/editing.html#the-hidden-attribute
element.setAttribute( 'hidden', '' ); element.setAttribute( 'hidden', '' );
element.setAttribute( 'aria-hidden', 'true' );
if( i < index ) { if( i < index ) {
// Any element previous to index is given the 'past' class // Any element previous to index is given the 'past' class
@ -1740,6 +1770,8 @@ var Reveal = (function(){
// Mark the current slide as present // Mark the current slide as present
slides[index].classList.add( 'present' ); slides[index].classList.add( 'present' );
slides[index].removeAttribute( 'hidden' ); slides[index].removeAttribute( 'hidden' );
slides[index].removeAttribute( 'aria-hidden' );
dom.statusDiv.innerHTML = slides[index].innerHTML;
// If this slide has a state associated with it, add it // If this slide has a state associated with it, add it
// onto the current state of the deck // onto the current state of the deck
@ -2391,6 +2423,8 @@ var Reveal = (function(){
if( !element.classList.contains( 'visible' ) ) fragmentsShown.push( element ); if( !element.classList.contains( 'visible' ) ) fragmentsShown.push( element );
element.classList.add( 'visible' ); element.classList.add( 'visible' );
element.classList.remove( 'current-fragment' ); element.classList.remove( 'current-fragment' );
//Announce the fragments one by one to the Screen Reader
dom.statusDiv.innerHTML = element.innerHTML;
if( i === index ) { if( i === index ) {
element.classList.add( 'current-fragment' ); element.classList.add( 'current-fragment' );

6
js/reveal.min.js vendored

File diff suppressed because one or more lines are too long