Supporting the Browser Back Button with Javascript

Browser back button support. When developing a Javascript-heavy, AJAX-riddled site, I often run into a 2.0 type of problem: supporting the browser back button. While it’s wonderful to build a site where users are brought to various content pages without the window refreshing, this excellent user experience will be completely ruined if you hit the back button and it returns you to the root of the site (or worse the last site you visited).

Thus, integrating the browser becomes an integral part of any Javascript developer’s toolkit.

Making the browser recognize Javascript changes

The first problem we have to solve is making the browser respect a Javascript change as a page change. However we have to be sure not to change the actual location of the page, or our AJAX or Javascript experience will be shot.

One thing to look at is the window location’s hash value (the thing in the url after the #). Remember from HTML 101 that when you click on a link pointed to #bottom, it sends the browser window to the on-page location of without refreshing the page.

Well it turns out that these hash links are useful to us since they are respected by the browser’s back button. So let’s try leveraging them to provide back button support for our key Javascript functions.

Adjusting the url’s hash value

First, we’ll have to create a function to modify the url’s hash value:

function set_hash( new_hash ) {

    window.location.hash = new_hash;

}

Call this from within whichever function you want to be tracked by the browser’s back button. Try it a few times. Notice how the back button is working and goes through the different hash locations.

While we’re off to a good start with the hash string, nothing is moving on the page just yet. To finalize our browser back button support we will have to do two things: first create a function to reset the page based on the hash location, and then build a listener for the url hash value.

The function to reset the page depends entirely on your setup. If you’ve used good object-oriented Javascript or AJAX it should be a piece of cake. We’ll call whatever this function is page_change(hash), where hash is the hash value that corresponds to a given page (duh). Feel free to modify this as you see fit.

Build a listener for the window’s hash value

Now we need to develop a Javascript listener for the value of window.location.hash:

var current_hash = window.location.hash;



function check_hash() {

    if ( window.location.hash != current_hash ) {

        current_hash = window.location.hash;

        page_change( current_hash.substr( 1,  current_hash.length) );

    }

}

Here we check to see if the hash location has changed, and if so we run the page_change() function. Notice that we used the Javascript substr() method to remove the first character of the hash value. This is to remove the ‘#’.

Notice also that we defined the variable current_hash outside of the function to store the hash value. You can integrate both of these into an object if you wish.

With the check_hash() function built, we are ready to complete our hash value listener. Let’s turn to Javascript’s trusty setInterval() method:

hashCheck = setInterval( "check_hash()", 50 );

This will run the check_hash() function every 50 milliseconds, which is plenty fast in my opinion. Don't set the time value too low here, since there is no reason to bog down processors: 50 milliseconds is barely noticeable to the user, who is expecting at least a slight pause as the new page loads up (remember they just hit the browser's back button).

A note on the page_change() function

Please note that we are now using the page_change() function that you built to change the page around every time the hash value changes. Thus this page change will occur whether the user hits the back button, or the hash is simply changed by set_hash(). Therefore you should either sub out whichever function you are using to change/build the page, or remove anything that might cause the page to be loaded twice.

Additionally, if you'd rather not run the page_change() function each time you set a new hash, simply modify the set_hash() function like so:



function set_hash( new_hash ) {

    current_hash = new_hash

    window.location.hash = new_hash;

}

This will change the current_hash value, thus preventing the page from reloading (barring some disastrously slow computer that runs the hash_check() interval in between setting the current_hash and changing the window.location.hash).

Be Sociable, Share!

Tags: , , , , , , ,

6 Responses to “Supporting the Browser Back Button with Javascript”

  1. GK Says:

    Great post, thank you!

  2. Elad Says:

    Thanks finally a decent tutorial just have to fight with the freaken “page_change()” function to do waht I want which is kind of hard..

  3. ben Says:

    Very nice, thanks for the inspiration 🙂

  4. Matty G Says:

    This works perfectly (with a few modifications) on Firefox, Opera, Chrome and Safari. But when I try it in IE7 or earlier, it goes back to the last fully loaded page. Any ideas on how to fix that?

  5. Jonah Bron Says:

    Really nice post. Very helpful. Thanks!

  6. Gus Says:

    Note – the setInterval call and global current_hash variable aren’t necessary in modern browsers (FF, Chrome, IE8+) as you can listen to the hashchange event:

    window.addEventListener(“hashchange”, page_change);

    function page_change() { alert(window.location.hash) }

    window.location.hash = “#test”;

    That’s all you need.