Ajax content, jQuery page transitions and why you should ditch the browser refresh

no browser refresh

Down with the browser refresh

I’ve just finished a project I’ve been working on over the last couple of months that was a jQuery-based ajax application without page refreshes. I thought I’d take this opportunity to share some of the problems I encountered whilst they were still fresh in my mind.

If you’re thinking of making your own jQuery online app I’d recommend trying out the ‘no refresh’ method. Once you’ve got it working, you’ll wonder how you’ve managed to cope so long with all these page refreshes, and each time somebody else’s site forces your browser to refresh, you’ll throw up a bit in your mouth.

In my humble opinion, asynchronous data transfer is the future and soon it will be very unusual to have your page refresh every time you want to see new content. Browser refreshes are clunky, ugly are an unnecessary interruption to the user experience flow.

With jQuery and ajax ruling your content you can have:

  • Complete control over the user experience. While your user is waiting for a page to load, you can display a fancy loading graphic, or even a small film clip, or some music, or whatever you like. It makes for a much smoother page transition, which should have it’s own bullet . .
  • Smooth page transitions. Okay, this is part of the user experience too, but such an important part I thought it deserved a special mention. Instead of content loading, then appearing in drips and drabs as and when it finishes, you can display your loading graphic until the whole page is ready, and then use a pretty jQuery effect to display the new content. You can have the page slide in, gradually fade in or just appear, the point is the page is ready instantly, and the user is aware that they can now click on things and type.

“But what about all the disadvantages!?” I hear you cry. Well, yes, you’re right there are problems too, but I’m going to try and address these with solutions and workarounds I’ve been using.

xml in a browser

Problem #1 – You click on a link and your browser takes you straight to the content, but refreshes the page in the process. Bad browser! Bad!

If you’re building an ajax app, this is a big nono. Especially since it’s most likely that that page will have no layout, and just be some JSON/XML data.

The solution is to use a jQuery event handler to intercept the link and make it do what you want, overriding the default behaviour.

Tip: For my application, I added classes to each link element such as a.internal and a.external to distinguish between the two. If you don’t do this, external links will be loaded in your application instead of in a new tab/page. You can also add separate behaviour for external links then, such as displaying a popup informing the user they are leaving your site.


$('a.internal').live('click',function() {
var post_url = $(this).attr('href');
$.historyLoad(post_url);
return false;
});

This bit of jQuery should go in the $(document).ready section of your code. It intercepts all links clicked of which have the class ‘internal’, sends their ‘href’ attribute to the historyLoad function, and then returns false to prevent the link from opening a new page.

But that’s not the only problem you’re likely to encounter.

empty browser

empty browser

Problem #2 – You scroll halfway down the page, click on a link and the content loads above the point your looking at.

If you’re displaying a lot of content, that requires vertical scrolling, you might find that when you click on a link to a page displayer less content, this content gets injected above the browser’s viewport. In other words, the new page is shorter than the old one and you need to scroll up to view it.

If you’ve never heard of ajax or jQuery before, you’re probably not going to realise that simply scrolling up will solve this one, so it’s good practice to cater for these people.

There is a simple solution to this. Add the following code to your ajax ‘success’ function – the function that gets called when your ajax call returns with some data.


$('html, body').animate({scrollTop:0}, 'fast');

This will take the user back to the top of the page before the new content is injected.

Start again from the beginning

Start again from the beginning

Problem #3 – going straight to a page deep in your application’s navigation structure.

So, you want to load up a bookmark you have from an article you read on the site six months ago? But wait! It just takes you to the home page and you need to wade through the navigation to get back to this article.

Because the page isn’t refreshing, neither is your browser registering the fact that you’ve changed pages. There is a workaround for this involving adding a unique hash code to the url using a nice little jQuery plugin. Please read my tutorial on the subject for more details, or google ‘jQuery history plugin’.

No room for overtaking here

No room for overtaking here

Problem #4 – Ajax requests jumping the queue

I didn’t encounter this problem for quite a while, but if you’ve got a page running without refreshes, chances are you’ll experience the same problem.

In jQuery, there’s no “request stack” or “request queue” for ajax. When you send off an ajax request, it comes back after the data you are rquesting has loaded, and only then.

Consider what might happen if you first click on a link for a page with 1000 images listed in one big row, and then get bored of waiting for this to load and click on a link for a single image. When you click on the second link (the one for the single image), it will not cancel the first request. So now you have two requests being processed by your server. Naturally, the single image is going to come back first. Great! That’s what we wanted. But as soon as the 1000 images have loaded, the ‘success’ function will get called and you’ll find your viewing experience unexpectantly interrupted.

To fix this you need to cancel any previous ajax requests before you initiate a new one. To do this, first declare a global variable to hold the details of any ajax requests your application will make:


var ajax_request = null;

This makes a variable that we can reference lateron to see if an ajax request is under way. Once we’ve got this we can create our ajax request:


if (ajax_request) { // checks for an existing ajax request
ajax_request.abort(); // aborts request
}
ajax_request = $.ajax({ // start the AJAX request
type: "POST", // I'm sending it via POST, you can use GET if you're feeling dangerous
url: post_url, // the URL we are retrieving
data: null, // in this case we are not sending any data
success: function(data) { // execute the below if the AJAX goes according to plan
//alert("success!");

// you can now inject the ajax response into any element you like witht the 'data' variable

});
});
},
error: function (XMLHttpRequest, textStatus, errorThrown) { // execute this if it all goes tits up
alert(textStatus + errorThrown);
return false;
}
});

In this example, the ajax request will be sent regardless, but jQuery will cancel any previous requests, to avoid the requests overtaking eachother.

Tip: If you would like more complex queue behaviour it might be worth checking out the jQuery Ajax Queue plugin.

Do you think this is all bullshit? That the browser refresh is here to stay? Or have you encountered other problems when ajaxifying your own website?

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>