Friday, August 21, 2015

How to Load In and Animate Content with jQuery

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.

$(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.

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

    // function here

});

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);

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;


Step 4


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


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'.

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:

$(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;

    

    });

});

Popular Posts