How to Load In and Animate Content with jQuery

Tutorial Details
  • Technology: jQuery
  • Difficulty: Intermediate
  • Completion Time: 1 hour

In this tutorial we will be taking your average everyday website and enhancing it with jQuery. We will be adding ajax functionality so that the content loads into the relevant container instead of the user having to navigate to another page. We will also be integrating some awesome animation effects.




So first of all, I have put together a very simple layout for this example. Here’s a screenshot and the HTML code we’ll use.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>mmm... Ajax!</title>
<script type="text/javascript" src="jquery.js"></script>
<style type="text/css">
@import url(css.css);
</style>
<script type="text/javascript" src="js.js"></script>
</head>
<body>
    <div id="wrapper">
    <h1>ajax ... nettuts</h1>
    <ul id="nav">
        <li><a href="index.html">welcome</a></li>
        <li><a href="about.html">about</a></li>
        <li><a href="portfolio.html">portfolio</a></li>
        <li><a href="contact.html">contact</a></li>
        <li><a href="terms.html">terms</a></li>
    </ul>
    <div id="content">
        <h2>Welcome!</h2>
        <p>Text</p>
    </div>
    <div id="foot">Tutorial by James for NETTUTS</div>
</div>
</body>
</html>

Step 1

First thing’s first, go and download the latest stable release of jQuery and link to it in your document:

<script type="text/javascript" src="jQuery.js"></script>

One of the best things, in my opinion, about jQuery is it’s simplicity. We can achieve the functionality described above coupled with stunning effects in only a few lines of code.

First let’s load the jQuery library and initiate a function when the document is ready (when the DOM is loaded).

$(document).ready(function() {
	// Stuff here
});

Step 2

So what we want to do is make it so that when a user clicks on a link within the navigation menu on our page the browser does not navigate to the corresponding page, but instead loads the content of that page within the current page.

We want to target the links within the navigation menu and run a function when they are clicked:

$('#nav li a').click(function(){
	// function here
});

Let’s summarize what we want this function to do in event order:

  1. Remove current page content.
  2. Get new page content and append to content DIV.

We need to define what page to get the data from when a link is clicked on. All we have to do here is obtain the ‘href’ attribute of the clicked link and define that as the page to call the data from, plus we need to define whereabouts on the requested page to pull the data from – i.e. We don’t want to pull ALL the data, just the data within the ‘content’ div, so:

var toLoad = $(this).attr('href')+' #content';

To illustrate what the above code does let’s imagine the user clicks on the ‘about’ link which links to ‘about.html’ – in this situation this variable would be: ‘about.html #content’ – this is the variable which we’ll request in the ajax call. First though, we need to create a nice effect for the current page content. Instead of making it just disappear we’re going to use jQuery’s ‘hide’ function like this:

$('#content').hide('fast',loadContent);

The above function ‘hides’ the #content div at a fast rate, and once that effect finished it then initiates the “loadContent” function (load the new content [via ajax]) – a function which we will define later (in step 4).


Step 3

Once the old content disappears with an awesome effect, we don’t want to just leave the user wondering before the new content arrives (especially if they have a slow internet connection) so we’ll create a little “loading” graphic so they know something is happening in the background:

$('#wrapper').append('<span id="load">LOADING...</span>');
$('#load').fadeIn('normal');

Here is the CSS applied to the newly created #load div:

#load {
	display: none;
	position: absolute;
	right: 10px;
	top: 10px;
	background: url(images/ajax-loader.gif);
	width: 43px;
	height: 11px;
	text-indent: -9999em;
}

So, by default this ‘load’ span is set to display:none, but when the fadeIn function is initiated (in the code above) it will fade in to the top right hand corner of the site and show our animated GIF until it is faded out again.


Step 4

So far, when a user clicks on one of the links the following will happen:

  1. The current content disappears with a cool effect
  2. A loading message appears

Now, let’s write that loadContent function which we called earlier:

function loadContent() {
	$('#content').load(toLoad,'',showNewContent)
}

The loadContent function calls the requested page, then, once that is done, calls the ‘showNewContent’ function:

function showNewContent() {
	$('#content').show('normal',hideLoader);
}

This showNewContent function uses jQuery’s show function (which is actually a very boring name for a very cool effect) to make the new (requested) content appear within the ‘#content’ div. Once it has called the content it initiates the ‘hideLoader’ function:

function hideLoader() {
	$('#load').fadeOut('normal');
}

We have to remember to “return false” at the end of our click function – this is so the browser does not navigate to the page

It should work perfectly now. You can see an example of it here: [LINK]

Here is the code so far:

$(document).ready(function() {

    $('#nav li a').click(function(){

    var toLoad = $(this).attr('href')+' #content';
    $('#content').hide('fast',loadContent);
    $('#load').remove();
    $('#wrapper').append('<span id="load">LOADING...</span>');
    $('#load').fadeIn('normal');
    function loadContent() {
    	$('#content').load(toLoad,'',showNewContent())
    }
    function showNewContent() {
    	$('#content').show('normal',hideLoader());
    }
    function hideLoader() {
    	$('#load').fadeOut('normal');
    }
    return false;

    });
});

Step 5

You could stop there but if you’re concerned about usability (which you should be) it’s important to do a little more work. The problem with our current solution is that it neglects the URL. What if a user wanted to link to one of the ‘pages’? – There is no way for them to do it because the URL is always the same.

So, a better way to do this would be to use the ‘hash’ value in the URL to indicate what the user is viewing. So if the user is viewing the ‘about’ content then the URL could be: ‘www.website.com/#about’. We only need to add one line of code to the ‘click’ function for the hash to be added to the URL whenever the user clicks on a navigation link:

window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-5);

The code above basically changes the URL hash value to the value of the clicked link’s ‘href’ attribute (minus the ‘.html’ extension. So when a user clicks on the ‘home’ link (href=index.html) then the hash value will read ‘#index’.

Also, we want to make it possible for the user to type in the URL and get served the correct page. To do this we check the hash value when the page loads and change the content accordingly:

var hash = window.location.hash.substr(1);
var href = $('#nav li a').each(function(){
    var href = $(this).attr('href');
    if(hash==href.substr(0,href.length-5)){
        var toLoad = hash+'.html #content';
        $('#content').load(toLoad)
    }
});

With this included here is all the javascript code required: (plus the jQuery library)

$(document).ready(function() {

    // Check for hash value in URL
    var hash = window.location.hash.substr(1);
    var href = $('#nav li a').each(function(){
        var href = $(this).attr('href');
        if(hash==href.substr(0,href.length-5)){
            var toLoad = hash+'.html #content';
            $('#content').load(toLoad)
        }
    });

    $('#nav li a').click(function(){

    var toLoad = $(this).attr('href')+' #content';
    $('#content').hide('fast',loadContent);
    $('#load').remove();
    $('#wrapper').append('<span id="load">LOADING...</span>');
    $('#load').fadeIn('normal');
    window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-5);
    function loadContent() {
    	$('#content').load(toLoad,'',showNewContent())
    }
    function showNewContent() {
    	$('#content').show('normal',hideLoader());
    }
    function hideLoader() {
    	$('#load').fadeOut('normal');
    }
    return false;

    });
});

Finished…

The great thing about this method is that’s it’s adaptable and can be applied to a site within minutes. It’s fully unobtrusive and the website will work normally if the user has JS disabled.

View the Final Working Example

Download the HTML, JS, CSS & Images

James Padolsey is JimmyP on Codecanyon
Add Comment

Discussion 568 Comments

Comment Page 1 of 101 2 3 ... 10
  1. Mark Provan says:

    Nice. Could really use this on my new project. Thanks alot.
    Mark

  2. Tuna says:

    Awesome. Keep it coming, I love it.

  3. The final effect looks great, especially with such a small amount of code, thanks :)

  4. Razvan says:

    Excellent, thanks for the tut! :)

  5. Fanou says:

    Really nice effect ! Thx for the Tutorial !

    But do you know how to do that with Mootools ?

  6. Claudiu says:

    great work! I love it!

  7. Omkar says:

    Wow thats brilliant!

  8. ijajaja says:

    Awesome!! Thanks for sharing !!!

  9. Nice. I can really use this on the next app i make …. will feature a link on my blog as well.

  10. Robin says:

    James,
    Thanks much for the tutorial. Good example of the power of Jquery!

    On another note… has anyone built something like this and ran it through Google Analytics to see if it tracks the clicks to the individual page sections? If it doesn’t work, could be a big issue with clients.

  11. Robin says:

    Sorry to double post,

    @James

    Is there a way to make this step back through the section transitions when hitting the browser’s back button?

  12. Dmitri says:

    Great, however browser’s back button functionality gets broken when you use such trick. I guess it would be very nice to provide the fix in following tutorials.

  13. D. Carreira says:

    Thanks! I was looking for something like this a month ago…

    Great tutorial!

    David Carreira

  14. makalu says:

    it’s amazing! really cool

  15. Shaein says:

    Great work! Looks very nice!

    There’s just this little thing..

    When switching to another page the content doesn’t seem to change. And I’m using Opera 9.50 beta. That could be the reason :P.
    Version:
    9.50 beta
    Build
    9945

    It did work on Fx beta 3 and IE7 though.

  16. James says:
    Author

    Thank you for all the kind comments!

    @Robin –

    Very important issue raised. If this functionality was ever integrated into a real-life project you’d have to seriously consider the usability of the website. The tutorial allows bookmarking (with the hash vaues) but doesn’t cater for the BACK button.

    There are various solutions available on the web although I didn’t think of it as necessary to include them in this tutorial seeing as it was more of an introduction…

    If you’re interested then have a look here:
    http://dev2dev.bea.com/pub/a/2006/01/ajax-back-button.html
    http://www.isolani.co.uk/blog/javascript/FixingTheBackButtonThatAjaxBroke

    As far as I can see, it seems to be about manipulating the browser history object.

    And that’s a good question about Google Analytics, if they don’t yet offer it maybe it would be something for them to consider for the future.

    @Fanou –

    I’m sure it could be achieved with mooTools, – Have a look at the ajax class – http://docs.mootools.net/Remote/Ajax.js#Ajax

  17. Medium says:

    I once asked something like this to be made as a tutorial so thank you net tuts for this :)

    @James
    When i go and type #about or #portfolio it does not work. I tried in firefox 3 & IE 6.
    It changes URL and content when i click on the nav buttons, but it does not load different content when i type the URL manualy. And this is a very big thing.

  18. Peter Butler says:

    Excellent tutorial and loads of help, thank you

  19. Tony Mathew says:

    Amazing effect, thanks for teaching us!
    It will sure come useful when i finally decide to make a portfolio

  20. Zé Miguel says:

    Cool Tutorial! Tanx!
    Can you tell me the font you used in the banner though? thanx

  21. Patrick says:

    The problem with this technique is that when you click on the back button of your Browser, nothing happens. Even though the effect looks great and is pretty cool, I do not see why one would implement this effect on a Website. But I have to admit, it looks cool.

  22. Chris Coyier says:

    Extremely nice, great work!

    I did a site like this one, and it was suggested to me to use the jQuery History plugin, which restores the functionality of the “back” button in the browser which would be great for this tutorial.

  23. mike says:

    Interesting tutorial and a pretty cool effect but not very practical.
    Using this you lose all your page titles, the ability to highlight the current page in the navigation menu, and, as Robin already pointed out, you may as well cancel your subscription to google analytics.
    Having said that, it does give food for thought and with a lot of work suggests some interesting possibilities.

    • Oberto says:

      “Using this you lose… the ability to highlight the current page in the navigation manu”

      it can be done. All you need to do is to set class (for example “active”) to clicked element and remove that class from others. This class can hold, I don’t know, maybe different bg color. This way what you clicked is highlighted (or changed font, color, whatever you want)

  24. Peter says:

    Overall a very nice effect, but I do perceive one flaw in this tutorial: the content should not “reappear” until the content of the new page is loaded. What happens when you click the link is that the previous page’s info reappears and then changes to the new content a second or so later. Is there a way to delay the content reappearing until it actually loads?

  25. Shane says:

    Interesting effect, but as a few people have pointed out, from a usability point of view, I don’t feel it’s best to theme an entire site around the effect.

    That said, your tutorial is well written and is yet another example of jQuery in action. I’ve done similar stuff in the past, but have concentrated on smaller areas of content.

    thanks :)

  26. James says:
    Author

    @Medium – That is because the page does not reload when you type a hash value in and the hash values are only checked upon page load. The hash values take effect when the page loads… So if you were to click this link it would take you to the #about page –> http://nettuts.s3.amazonaws.com/011_jQuerySite/sample/index.html#about

    If you want to automatically and continually check the hash value you could add a timeout function to do that. (e.g. maybe check every 500 milisecs) – I have not tried this so I don’t know if it would work… Typing the hash value in seems to work in Safari3 – I havn’t tried any other browsers.

    With little support available for Ajax apps across browsers you might feel uncomfortable using this solution for an entire site but it is still very useful for smaller widgets and inner content.

    @mike – Changing the page title is possible and having active link styles on the nav menu is also possible. – I have not included them in this tutorial though because I didn’t want it to get too crowded ;) … The google analytics thing would be quite an issue and there are various other usability issues, but it still (like u said) is food for thought and hopefully this is a taster (no pun intended) of things to come in the future of the web.

    @Shane – I think you’re right about it not being a perfect solution for an entire site. Like you pointed out, this effect is more suited to smaller areas of content. :)

  27. Cool, nice and simple site, if i were to use this i would have my different social profiles embedded in them or for simple data maybe to show off an app

  28. Danny says:

    This is really cool

  29. Bruce Alrighty says:

    Great tutorial.

    I think the effect would better suited in a sidebar though, instead of the whole website.

  30. shofr says:

    I wonder how this would effect SEO. A spider would see each separate HTML file, which might not be ideal depending on the content.

  31. Tony Mathew says:

    When I add this script to a page as well as the ligthbox script they conflict and whichever script is first always seems to win.
    Is there any way for this script to work in harmony with the lightbox script on the same page?

  32. Louie says:

    Wow I like this tutorial. Many thanks :)

  33. Great tut. Two thumbs up!

  34. Snorri3D says:

    nice tutorial :)
    more AJAX related would be great :D

  35. Andrew says:

    Your tutorials on this and PSD Tuts are consistently awesome. Thanks!

  36. x says:

    Just pointing out some errors in the tutorial:
    - The link is missing in Step 4 ( “It should work perfectly now. You can see an example of it here: [LINK]“)
    - Code is not indented properly – the wrapper div in the first block, the big code blocks in step 4 and 5
    - You should extract the file-name using regexp (or indexOf etc.) instead of just removing the last 5 chars:
    href.replace(/(\..+?)?$/,”)
    or
    href.slice(0,href.indexOf(‘.’))
    .. What will happen if the href contains full path or links to a different domain (e.g. http://www.google.com/ )?

    • Paul M says:

      Hi mr X!
      Could you please contact me per e-mail I have a small problem pertaining some ambiguities in IE8!

      Iam in desperate need of a solution…..
      /P

  37. Adam says:

    One of the BEST on this site so far! Great Stuff!

  38. Eric Orr says:

    Very cool effect.

  39. Marko Novak says:

    I don’t know if anyone mentioned this already, but with this method you disable browser back button. Which is in my opinion bad option. Other than that, it’s a very nice tutorial.

  40. sinan says:

    thank you.goog tutarial.

  41. eod says:

    cool, perfect for portfolio, thanks for sharing

  42. James says:
    Author

    THANKS FOR ALL THE COMMENTS!!! :)

    I have had a go and using the jQuery history plugin (Thanks for the tip Chris Coyier!) I have made it possible to use the back button.

    The new script (js.js) is actually shorter now, and you can get it here: http://www.qd-creative.co.uk/uploads/projects/ajaxtut/js.js

    You need to download the history plugin for this to work: – http://www.mikage.to/jquery/jquery.history.js

    So you should be linking to three scripts at the top of your document now:

    I’ve tried this out on Firefox and Safari (seems to work very nicely) …

    I haven’t updated the original tut files or the tutorial because it might just end up confusing people.

  43. James says:
    Author

    @Tony – Lightbox uses the prototype library which uses the same ($) function caller and so there is a “conflict” between jQuery and Prototype.

    I’m sure there are other solutions available but this ( http://codingforums.com/showthread.php?t=120309 ) thread seems to offer some help. (POST#4 is probably what ur after)

  44. Ahmad Alfy says:

    It looks cool!

    but I’m worried about accessibility and seo stuff

    I suggest it should be used within web apps … where users have to login to acess data

  45. James says:
    Author

    Just a note, I have created a fix to the various usability issues (like using the back button) – I have detailed the fix in a comment, but it is awaiting moderation… (because it has links in it I think)

  46. wow what a tutorial, very simple and effective to understand, I wish many people could explain things like you
    and of course great effect, I like it also because it’s fully accessible. of course it’s a great thing for some kind of websites, or some areas of websites, very usable but it needs to be used in the right way and not just because it looks “cool”

  47. linzprod says:

    Hats off to you!

    Nice tut. thanx a lot.

  48. jd says:

    Very nice tutorials! Many thanks!

  49. BroOf says:

    I love you :D And i love JQuery :D! Thank you for posting this!

  50. This site is very good.

    I have helped many times :)

    MIGUEL PEREIRA

Comment Page 1 of 101 2 3 ... 10

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.