AJAX is easy, but remember accessibility
January 18, 2009
AJAX is easy. It’s just javascript talking to your server to grab a little bit of content instead of the browser grabbing the whole thing. With this in mind, let’s get to work and build a simple AJAX application that will work with javascript turned off. We’ll do this by assuming that there is no javascript in your user’s browser, then use jQuery to change the DOM to add in the behaviours.
So first things first, I just want to lay down a few requirements for this faux-project. I want this to be properly simple, so it would be great if the regular content and AJAX content could come from the same place. I want the pages to work properly for people with no javascript. I want people with javascript to load in the new content using AJAX, but very importantly, I want them to be able to send a link to their friends or bookmark the content they are viewing. This is something which people often look over when building their AJAX applications, so normally if you send a link to someone, they’ll get the ‘front page’ instead of the information which the sender was looking at. So let’s split the project up into four parts:
- Build the website using a bit of PHP magic so that either the whole page, or just the AJAX content can be loaded;
- Use jQuery and HIJAX to update the content instead of loading the whole new page if the user has javascript enabled;
- Create a mechanism so that people can send a link or bookmark the page;
- and finally, load in the relevant content instead of the default content if someone uses one of their bookmarks
Part 1: The PHP
For this tutorial, I’m just going to create a very simple page with just a navigation bar and content area. I will split each page up into three parts: files for the header and footer as these will be the same for all pages, and the page itself, which will include the header and footer.
Inside the header and footer is where the magic will happen. For AJAX calls, I will pass a GET parameter to the page (I have chosen AJAX=1, but you can choose whatever you like), but normal page loads will not have this. Using this technique is a great way to test your output too – if you want the full page, just go to it’s url (i.e. http://example.com/page.php), if you want the AJAX content, stick ?AJAX=1 on the end (e.g. http://example.com/page.php?AJAX=1).
header.php
Example AJAX website
footer.php
a-page.php
Example page
My content
Part 2: HIJAX
So far the pages work for people with javascript disabled, which includes our friends, the search engines. By adding in the href to the anchors instead of just onClick handlers, the site is fully navigable and accessible to everyone. Wouldn't it be great if we could keep this code the way it is and somehow magically get the AJAX working without modifying this at-all?! Well, the great news is that with HIJAX, we can.
The first thing to do is to use jQuery to find the elements which we would like to load in content via AJAX, and inject some behaviour into them. In my example, they are the anchor tags inside the navigation div. I will use jQuery to find those, add in the AJAX behaviour (which will load in the content from the same page, but with ?AJAX=1 appended) and disable them from loading in a whole new page. The next thing to do is to get them to update the address bar so that bookmarking / linking will show the correct content.
Part 3: Linking mechanism
If you are familiar with Gmail or Facebook, you might have noticed that when you click around, the address bar changes. They use the document's hash to indicate what page of the site you are currently on. I like this mechanism, so I will do the same.
It's quite easy really, along with the AJAX call on the onClick, we can set the location.hash
javascript variable to be the href of the anchor tag which the user clicked. One line of code will deal with that.
Part 4: Dealing with the linking mechanism
Imagine the scenario: Someone comes into your website at page1.php, then clicks on a link to page2.php which is loaded in through AJAX. They bookmark the page. Now the URL points to page1.php and we need content from page2.php. We know that we want the content from page2.php because the hash will indicate this. So we can just get jQuery to load in the content (which we can do because we know the page to get the content from (from the hash), and just append it with ?AJAX=1).
Putting it all together
You might be surprised that you can build a fully functioning AJAX site with just 10 lines of jQuery (and it could be a lot less). I say you can, and here's the code for all three of the above steps. (Obviously it's longer than ten lines because I have put in some comments, but strip them out and it's only ten!)
$(function() {
// Part 4
if (location.hash)
{
// the substring is to get rid of the '#' at the beginning
// the $.get function takes three arguments:
// the page to load
// any GET parameters (in this case AJAX=1
// what to do on success. (in this case update #content-area
$.get(location.hash.substring(1), {AJAX:'1'}, function(data) {$("#content-area").html(data);})
}
// Part 2: the HIJAX.
// (in this case, add AJAX calls to all anchors in #navigation)
$("#navigation a").click (function () {
// load in the new content (from the same page as the anchor's href attribute)
// then put the resulting html into #content-area
$.get ($(this).attr("href"), {AJAX:'1'}, function(data) {$("#content-area").html(data);});
// and this line is for part 3
location.hash=$(this).attr("href");
// this stops the browser from loading the whole page
return false;
});
});
Whether you put this into an external javascript file, or at the bottom of footer.php is up to you. In the example, I have put it at the bottom of footer.php. To see the fruits of my labour in action, visit the Example Accessible AJAX website. You might like to also try visiting page 1 (which you'll notice is loaded in by the javascript, so you see the content for page1.php even though you initially load index.php). And of course, you could just look at the AJAXified content. As usual, I have zipped up all of the files used in this tutorial for you to download.
Final thoughts
This tutorial only scrapes the surface of AJAX, so while this is a starting point, it is by no means ready for deployment for live sites. Ofcourse, it works, but there are other things that you will need to consider (a 'web 2.0' loading animation? What do you want to do if the hash points to a page which doesn't exist? Are there other parts of the page which need to be updated too (i.e. the title bar, sub navigation or tactical boxes)?).
It might be more desirable for you to have a single (or a few) php file(s) which deal with all of the AJAX requests rather than each page delivering both regular and AJAX versions of the same content. This will definitely be the case in websites using MySQL or similar rather than flat static files like in the example. Also you might like to look at other ways to deliver the content (after all, the X in AJAX stands for XML), both jQuery and PHP have support for JSON, I would suggest having a look at that.
Forwards and back buttons: currently they have no effect on the site. Would you like your users to be able to go back a page by pressing the back button? I would recommend this. There a plenty of plugins out there which will help you to complete this task.
Finally, DON'T, for god's sake, use AJAX just because you can! There is really no need for me to have used it in the example (other than it was about AJAX, of course), there is nothing more annoying to me than a website which uses AJAX because the author had read about it the night before. Please don't be one of those people!
Have I missed anything out? What are your thoughts?
Grab the files
You can download the files used for the example site here.