How to get a screen reader to stop reading and read different content

Scott picture Scott · Mar 28, 2012 · Viewed 17.5k times · Source

I've written a site that uses jQuery to display a modal popup. It essentially covers the entire viewable area of the screen with an overlay, then shows a DIV that contains the actual popup on top of the overlay. One of the requirements for this project has to do with accessibility.

When the page loads, the screen reader starts reading from the top of the page. When a user clicks on a particular link, we display a modal dialog. My question is: how do I interrupt the screen reader's reading of the main portion of the site and tell it to start reading the dialog text?

My modal container is wrapped in a div like this:

<div id="modalcontainer"  tabindex="0" class="popup" role="dialog" aria-labelledby="dialog-label" >

The jQuery that fires the modal looks like this:

$("#modalLink").click(function (e) {
    e.preventDefault();

    $("#modalcontainer").center();
    $("#modalcontainer").show();
    $("#closeBtnLink").focus();
    $("#wrapper").attr('aria-disabled', 'true');
});

The "closeBtnLink" is the close button within the modal dialog. I would have thought setting the focus on this would instruct the screen reader to start reading from that element.

The "wrapper" element is a SIBLING of the modal dialog. Per a suggestion from another SO user for different reasons, I set "aria-disabled=true" on the wrapper element that contains the entire page. The modal dialog exists as a sibling outside of this container.

My main goal here is to get the screen reader to read the contents of my modal DIV element when they click on a specific link. Any help would be appreciated.

Answer

albert picture albert · Apr 13, 2013

This can be accomplished using ARIA role="dialog". you'd have to modify this code for your example, it's vanilla js, so yours will probably be shorter/easier via jQuery.

HTML:


<div role="dialog" aria-labelledby="myDialog" id="box" class="box-hidden" tabindex="-1">
  <h3 id="myDialog">Just an example.</h3>
  <button id="ok" onclick="hideDialog(this);" class="close-button">OK</button>
  <button onclick="hideDialog(this);" class="close-button">Cancel</button>      
</div>

JavaScript:


var dialogOpen = false, lastFocus, dialog, okbutton, pagebackground;

function showDialog(el) {
    lastFocus = el || document.activeElement;
    toggleDialog('show');
}
function hideDialog(el) {
    toggleDialog('hide');
}

function toggleDialog(sh) {
    dialog = document.getElementById("box");
    okbutton = document.getElementById("ok");
    pagebackground = document.getElementById("bg");

    if (sh == "show") {
        dialogOpen = true;

        // show the dialog 
        dialog.style.display = 'block';

        // after displaying the dialog, focus an element inside it
        okbutton.focus();

        // only hide the background *after* you've moved focus out of the content that will be "hidden"
        pagebackground.setAttribute("aria-hidden","true");

    } else {
        dialogOpen = false;
        dialog.style.display = 'none';
        pagebackground.setAttribute("aria-hidden","false");
        lastFocus.focus(); 
    }
}


document.addEventListener("focus", function(event) {

    var d = document.getElementById("box");

    if (dialogOpen && !d.contains(event.target)) {
        event.stopPropagation();
        d.focus();
    }

}, true);


document.addEventListener("keydown", function(event) {
    if (dialogOpen && event.keyCode == 27) {
        toggleDialog('hide');
    }
}, true);  

source: http://3needs.org/en/testing/code/role-dialog-3.html
more reading: http://juicystudio.com/article/custom-built_dialogs.php