Silicon News

TwitterRSSEmail
The Leader in Technology News and Commentary.

The URL Hashtag and AJAX Content Loading

Posted by Anthony on July 12, 2012 in Software

jQuery Logo

Or: “Laziness can be productive”

Ever seen how Twitter and other sites load pages via AJAX, dependent on the hashtag within the URL?

Implementing that on your site is easier than one might realize: all you need is a little jQuery, content, and optional server-side code to get it up and running – without sacrificing SEO.

And with a few extra lines of code, it can be made very pretty and HTML5-looking, too.

The jQuery Hashtag Plugin

This is the crux of it all: The plugin, written by Ben Alman, binds the browser’s window.onhashchange event to a function of your choosing. BUT, should the browser not support this event (*cough*OlderInternetExplorer*cough*), then the plugin implements it itself via a polling loop with no serious degradation in performance.

So, to start off the template page for running this, you would include jQuery and the plugin code (which is compressed) into your site’s JavaScript file, and bind the events via the “ready loop” like this:

Code   
$(document).ready(function(){
    $(window).hashchange(function(){
    // implemented elsewhere:
        parseHash();
    });
});

But hold your horses there, cowboy: the function within the event handler only accounts for changes to the hashtag after the page has loaded! What if the user pasted a link to the site that already has a hashtag at the end which signifies which page to load already? Easy enough to handle:

Code   
$(document).ready(function(){
     if(window.location.hash) { // Batteries included?!
          parseHash(); // Tweedle-dee
     }
     $(window).hashchange(function(){
          // implemented elsewhere:
          parseHash(); // Tweedle-dum
     });
});

There we go, now the hashtag will call the same handler regardless of whether it was included within the URL during the initial page load, or changed during the lifetime of the page. Now how about that parseHash function?

The AJAX

Now that we have a unified function, parseHash, to handle both the initial URL-passed hashtag as well as any hashtag changes in the future (more details to come), let’s analyze where the AJAX comes into play.

The parseHash function looks something along the lines of this:

Code   
function parseHash() {
     // retrieve target page from URL:
     var page = window.location.hash.split("#")[1];
 
     // assuming you have a div with id "content"
     $("#content").empty(); // remove old content 
     $("#content").load("/"+page,
     function(response, status, x) { 
          // handle non-existent hashtag pages: 
          if(status=="error") $("#content").load('/404'); 
     }); 
}

Cool, now any link with the hyperlink done like so:

Code   
<a href="#login">Click to load login page</a>

…Will load the hashtag-designated page into the content div via AJAX. But what about making it jive?

Animation

Animating the process is a very complex process involving quaternion numbers and three-dimensional transforms over Minkowski space via JavaScript and CSS, with quirks and browser extensions needed to make it work cross-platform.

Just kidding, all you need is this:

Code   
function parseHash() {
     // retrieve target page from URL:
     var page = window.location.hash.split("#")[1];
 
     // assuming you have a div with id "content"
     $("#content").fadeOut("slow", function() { // executed when animation complete 
          $("#content").empty(); 
          $("#content").load("/"+page,function(response, status, x) { 
               if(status=="error") $("#content").load('/404'); 
               $("#content").fadeIn("slow"); // bring it back in 
          }); 
     }); 
}

Now every time a user clicks a hash link, the content will gracefully fade out before fading the new content in. Nifty huh? BUT – what about SEO and compatibility? Fear not!

Server-side tweaks

All of this sounds great, except for one little thing: search engines don’t crawl AJAX content explicitly yet.

Solution? Easy – go ahead and keep the links pointed to the right pages the way they are, and as the page loads, use the same JavaScript/jQuery ready function to reset the “href” attributes of all anchor tags to their pages. Example:

Code   
$(document).ready(function(){
     // [...] earlier code [...]
 
     var h = null; // recycle
     // nav menu crawl:
     $("#menu > ul > li > a").each(function(i) {
          h = $(this).attr("href"); // recycle
          // your domain here:
          $(this).attr("href",h.replace("http://www.example.com/","#"));
          // Your link's been hash-tagged, yo!
     });
});

The JavaScript-ignorant search engine crawlers see the regular destination page, while the users get the pretty and nice hashtag AJAX links instead, handled by jQuery.

But what about the content of the link target pages? You can’t just load an entire web page into the AJAX content div, duplicating the header and all. So what’s the fix? A little server-side magic and a few characters of client-side code, it turns out.

If you’re using PHP to manage your header/footer content (like I do a la WordPress templates, though I only discovered its use of “my” method afterward), then do this:

Code   
<?php 
if(empty($_REQUEST["ajax"])) { // the trick      
    include "header.php"; 
} 
?>
Page-specific content to be loaded either directly or via AJAX goes here.
<?php 
if(empty($_REQUEST["ajax"])) { // the trick 
     include "footer.php"; 
}
?>

Alternatively, you can just modify the “header.php” and “footer.php” files to exit early if the parameter exists to avoid duplicating template content, instead of editing all files. The inverse conditional statement and the exit() PHP function are your friend there.

And the client-side edit to complete the magic:

Code   
function parseHash() {
     // retrieve target page from URL:
     var page = window.location.hash.split("#")[1];
 
     // assuming you have a div with id "content"
     $("#content").fadeOut("slow", function() { // executed when animation complete 
     $("#content").empty(); 
     // added: ajax=1 to end of the URL concatenation 
     $("#content").load("/" + page + "?ajax=1",function(response, status, x) { 
          if(status=="error") $("#content").load('/404'); 
          $("#content").fadeIn("slow"); // bring it back in 
          }); 
     }); 
}

Now search engines see regular links to full pages, and users see a nice AJAX site that loads content into a div as you intended – with added animations. Feel free to extend this for CSS 3D transformations, or any other embellishments.

Note: changing the links like this does not count as “cloaking,” or any other violation of Google’s web site guidelines for inclusion in its index.

Conclusion

There you have it! While most sites are more complex and require special attention for stuff like this (e.g. form processing, session management, analytics etc.) many sites can benefit from this little trick that users will appreciate.

The key here is the hashtag plugin: links work even when bookmarked or pasted, no more Flash-like issues where navigating further into the site is lost upon reloading the page.

Advanced topics not included here for the purpose of giving one a general overview of the process are: AJAX history management, protocol management and security (HTTPS versus HTTP and mixing the two), and other template-related issues such as making this work with ASP.NET’s templating system.

Best part is: it works on mobile browsers too ;)

Feel free to leave a comment, some link love, or any other form of appreciation for this. Thanks for reading.



About Anthony:

Anthony is the Silicon News editor-in-chief. Many dedicated readers know him from his prior blog The Coffee Desk before its sale in early 2010, which was featured in everything from Yahoo! News, Slashdot.org, and countless other news agencies pulling in millions of unique visitors a month. He has ample experience with software, hardware, and networking, having been employed by numerous companies ranging from U.S. government agencies, research and development firms and Google. Though his approach is usually technical and dry, he is notorious for his subtle and witty observational humor.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may 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>

(Spamcheck Enabled)

Copyright © 2012-2013 Silicon News All rights reserved.