Tutorial Menu

Basic AJAX - Making the AJAX class more accessible

As most screen readers require a click or keypress event to update the user we need to add in extra functionality to our class to make it more accessible. This needs to be applied this to all events that notify the user. This includes the onSend(), onLoad() and callback functions.

Setting the Focus

First define a variable to hold the identifier of the element to set the focus on in our class variables.

focusElement:false,

The script then checks to see if this is set in our focus function. If it is set then we assign a tab index of -1 if the tab index does not exist. This enables the element to be focusable without changing the tab order and then we set that element to be focused on.

setFocus:function(){
    if(this.focusElement!=false){
        if(!document.getElementById(this.focusElement).tabIndex ||
               document.getElementById(this.focusElement).tabIndex==-1){
            document.getElementById(this.focusElement).tabIndex = -1;
        }
    document.getElementById(this.focusElement).focus();
    }
},

Getting JAWS to update the virtual buffer

The next is to add the update buffer method. This places or updates a hidden input field on the page. Changing this value causes the JAWS screen reader to update the virtual buffer.

updateJaws:function(){
    if(!document.getElementById('virtualbufferupdate')){
        this._createUpdateField();
    }
    var updateObj=document.getElementById('virtualbufferupdate');
    if(updateObj.getAttribute('value')=='1'){
        updateObj.setAttribute('value', '0');
    }else{
        updateObj.setAttribute('value', '1');
    }
}

This function checks to see if the field already exists and then creates the field at the bottom of the page if it is missing. The function then updates the field triggering the buffer update in JAWS.

The following function creates the hidden input field and places it at the end of the document.

_createUpdateField:function(){
    var updateObj = document.createElement('input');
    updateObj.setAttribute('type', 'hidden');
    updateObj.setAttribute('id', 'virtualbufferupdate');
    updateObj.setAttribute('name', 'virtualbufferupdate');
    updateObj.setAttribute('value', '1');
    var paragraph = document.createElement('p');
    paragraph.appendChild(updateObj);
    document.body.appendChild(paragraph);
}

Although this is designed to inform a user of content changes the screen readers can sometimes behave unpredictably or the user could be running an old version of the software. On top of having this extra code it is suggested to make a help page that is easily discoverable by a screen reader. I suggest putting a link after any skip navigation or accessibility options at the top of the page.

The following information will be useful to a user with a screen reader.

This site uses JavaScript to update content. If you are using a screen reader and you activate a link or a form and nothing appears to happen you will be positioned at the updated content. Use the following appropriate keystroke to toggle the virtual cursor if this does not happen or no text is updated:

Screen ReaderKeystroke
JAWSInsert + z
Window-EyesControl + shift + a
SupernovaLeft Control + 4

If you still experience problems follow the link to access the non-script version.

I also recommend having a link to a non-JavaScript alternative version. This will inform the user of the JavaScript functionality and give the user the option of attempting to use the dynamic site with the AJAX calls.

Using the accessible AJAX class

A few changes must now be made to our html page to accommodate the new class. First the element to be focused must be set. The hidden loading div can also be removed as hidden content can be read out and confuse a user with a screen reader. Our new loading message is added to the page. Through styling we can position this anywhere on the page.

So the new page will look like the following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <title>My First Accessible AJAX  Call</title>
        <script type="text/javascript" src="accessibleAJAXClass.js"></script>
        <script  type="text/javascript">
          function makeCall(){
            var myAJAX= new AJAXClient();
            myAJAX.isAsync=true;
            myAJAX.focusElement='dataTarget';
            myAJAX.callback= function(result){
              document.getElementById('dataTarget').appendChild(
                   document.createTextNode(myAJAX.xmlhttp.responseText));
            }
            myAJAX.makeRequest('Data.txt', null);
          }
        </script>
    </head>
    <body>
       <div id="content">
          <h1>My First Accessible AJAX call</h1>
          <p><a href="javascript:makeCall()">Make Call</a></p>
          <p><span id="dataTarget"></span></p>
        </div>
    </body>
</html>

See example (opens in new window).

In order for this to be fully functional and accessible there should be a no-script alternative built in. The next tutorial takes the optimised AJAX class and uses it in situations where alternative solutions are partnered to catch any browser or user where AJAX is not possible.

Previous: Basic AJAX - Calling the AJAX class Next:Basic AJAX - Incorporating alternatives

References

Lemon, G., Faulkner, S. (2006, May 25) Making Ajax Work with Screen Readers. Retrieved March 31, 2008, from http://juicystudio.com/article/making-ajax-work-with-screen-readers.php

Lemon, G., Faulkner, S. (2007, January 19) Improving Ajax applications for JAWS users. Retrieved March 31, 2008, from http://juicystudio.com/article/improving-ajax-applications-for-jaws-users.php

Eichorn, J. (2006). Understanding AJAX. Upper Saddle River, NJ: Pearson Education, Inc.

Zakas, N. C. (2005). Proffessional JavaScript for web developers. Indianapolis: Wiley Publishing Inc.