Anchored based URL Navigation

Posted 15 Years Ago



I've been noticing a trend with AJAX based websites lately.  Of course, AJAX isn't new, but the method these websites used for navigation was new.  Instead of simply calling javascript on a click, then displaying the information inside the desired element these websites we're utilizing the built in functionality of HTML anchor tags to amend the URL which appears in a user's brower address bar.  The result is something like this:

http://hypem.com/#/artist/florence+and+the+machine

At first I thought it was a little curious, but I've since come to think it's rather ingenious.

Credit to the Originals

I first noticed this new technique on Hype Machine.  If you've never heard of it, it's a website which aggregates MP3's from hundreds of music blogs.  It's pretty nifty and recently they launched their entirely AJAX site.  The main advantage of this is that they can keep music playing while allowing you to navigate throughout the rest of the site.

Of course, they probably didn't invent this technique, but that's where I first noticed it and ever since I've stumbled across it on a handful of other sites including a little site called Facebook.

Before I move on I must also say I just searched for information on this new technique and found two excellent blog posts about it from Rebecca Murphy and YenDesign.
 

Alright, it's neat...so what?

Well, if you've worked extenstively with AJAX (or Flash for that matter) before you'll have noticed that one major drawback is that a user is always on the same URL.  That may not seem like a big deal, but say a user clicks three levels deep into your site, finds something cool, copies the URL and sends it to their friend.  Well, the friend now has to find that information all over again. 

This violoates what's called Progressive Enhancement strategy (Don't worry, I'd never heard of it before either).  Here's what Wikipedia has to say on the matter:

Progressive enhancement is a strategy for web design that emphasizes accessibility, semantic markup, and external stylesheet and scripting technologies. Progressive enhancement uses web technologies in a layered fashion that allows everyone to access the basic content and functionality of a web page, using any browser or Internet connection, while also providing those with better bandwidth or more advanced browser software an enhanced version of the page.

Anyway, the solution the world of web developers has come up with is rather ingenious.  The anchor tag is the only (to my knowledge) standard HTML thing which allows you to change a page's URL without reloading the page.  It stands to reason then this functionality can be used to maintain 'Progressive Enhancement' while still being able to utilize AJAX.
 

Well...it's kind of interesting...so how do I do it?

Well, I don't know . . . give me a minute...

Let's say we want to load photos.html, but with AJAX.  First, the link:

Anchor Nav Link
<a href="#photos.html" class="anchor">Photos</a>

Pretty basic.  Now, the second step is to be able to know when a user actually clicks this link.  I've seen two methods for this.  YenDesign stores the current URL then checks ever 300 milliseconds to see if that URL changes. I'm not so much a fan of that idea.  I prefer Rebecca Murphy's method of attatching an onclick event to anchor links.  I'm going to amend it a little though and add a class to each link I want to use this functionality.  We'll call this class 'anchor' (as you can see in my example above).

Now I'm going to use jQuery because . . . well, that's just the javascript library I use, but I'm sure you Scriptaculous and MooTools die hards can use your own methods

...actually, I'm going to jump ahead a few steps because I'm too lazy to write this all out.

Anchor Nav Javascript
<script type='text/javascript'>
$(document).ready(function() {
    anchors();
});
function anchors() {
    $("a.anchor").each(function() {
        $(this).click(function() {
            var a = $(this).attr('href').split('#')[1];
            if(a) loadAnchor(a);
        }).removeAttr('anchor');
    });
}
function loadAnchor(a) {
    alert(a);
}
</script>

Alright, so here's what the javascript is doing.
  • When the page loads it searches for all links with class="anchor"
  • It finds the anchor link within that link
  • If it found an anchor link it attatches an 'onclick' function to the link which executes the loadAnchor function
  • When a user clicks on a link, we alert the anchor link (just for showing we got this far).

Now it's just a matter of adding the AJAX call to our loadAnchor function.

Anchor Nav AJAX
function loadAnchor(a) {
    $.get(a,null, function(html){
        $("#content").html(html); 
    });
}

This loads the photos.html file into a div with id='results'.  Of course, this would also handle .php pages, even ones with query strings (I think, too lazy to test it right now).  You'd probably want to call the anchors function again to see if there are any new anchor links (which conflicts with the next step I'm about to describe, but I'll figure something out and let you know).

Now, there's only one more main function we need.  The real value of this technique is that users can return to the same page using the new URL.  So let's work that into the javascript:

Reload Anchor URL
function anchors() {
    $("a.anchor").each(function() {
        $(this).click(function() {
            var a = $(this).attr('href').split('#')[1];
            if(a) loadAnchor(a);
        }).removeAttr('anchor');
    });
   
    var url = document.location.toString();
    var a = url.split('#')[1];
    if(a) loadAnchor(a);
}

I worked the code into the 'anchors' function so it too gets called when the page loads.  Of course, the problem with javascript is you have to wait for the page to load for this to happen which is a bit annoying, but what can you do.

Anyway, this is a pretty basic example.  Her'es a demo of what I just did:

Demo


And here's the imortant source code:

Source Code
$(document).ready(function() {
    anchors();
});
function anchors() {
    $("a.anchor").each(function() {
        $(this).click(function() {
            var a = $(this).attr('href').split('#')[1];
            if(a) loadAnchor(a);
        }).removeAttr('anchor');
    });
   
    var url = document.location.toString();
    var a = url.split('#')[1];
    if(a) loadAnchor(a);
}
function loadAnchor(a) {
    $.get(a,null, function(html){
        $("#results").html(html); 
    });
}
</script>

<h1>Anchor Based URL Navigation</h1><br />
<a href='#photos.html' class='anchor'>Photos</a>

<div id="results"></div>

I'll try and work this into a jplugin-in the next few days.  Let me know if you have any suggestions.