A beginners guide to animating fade between two images in jQuery

A while back, a friend of mine who is a javascript newbie and not a developer was tasked with updating a wordpress template. Part of the update was to have a black & white image fade into a colour image when a user hovered over it.

On her own initiative, she found this tutorial at baotasan.com which helped her out a bit. The problem she had was that while the solution she found there worked, she didn't understand why it worked. I wrote up a step by step explanation of the code and am posting it here in case anyone else finds it useful.

First of all you'll need to load jQuery onto your page, otherwise you won't be able to use it. The easiest way to do this is to put the following line into your header (in between the <Head> and </Head> tags).

<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'></script>

This tells your browser that you want to load some 'script' of type javascript, and that the javascript file that you want to load is located at 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'. 

There are essentially 2 ways you can load jQuery. The first is to download a copy, which you host on your own server. The tutorial you were looking at assumes you have done this, which is why they have the 'http://yoursite.com/jquery.js' address - where you would replace 'yoursite.com' with the link on your site where the file is. The second way - which is easier and safer, is to use the 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' link which I have put in the line for you to copy and paste. This link always points to the latest version of jQuery and therefore you get all the security fixes and updates automatically. It also means you don't have to download any files and it's just easier all round.

So, now that jQuery is being loaded onto your page, you need to get it to actually do stuff. 

The effect you want requires two images. One in greyscale and the other in colour.

The first step you need to do is to put them both on your page, inside a div tag. I'll assume you know what divs are if you're making a website, if not, there are plenty of good beginner tutorials out there that should be easy to find.

The code you'll want to use should look roughly like this:

<div class="fadehover">
	<img src="black-and-white-image.jpg" alt="" class="a" />
	<img src="colour-image.jpg" alt="" class="b" />
</div>

So far this is all just html and css. You create a div, pop your two images inside the div (you'll need to change the 'src' values to the actuall images), and asign everything a class value so you can style it all nicely later.

The CSS (the <style> down to and including the </style> tag can just be copied and pasted into your page somewhere - ideally the header again). All this says is that you want to align both images exactly at the top left corner of your div. The 'z-index' bit says that image 'a' (the greyscale one) is on top ( the higher the value, the further up it is) and therefore this is the image that will be visible on load.

So now you have a page, with jQuery laoded, and with two images, one on top of the other. Now onto the cool stuff.

First of all we have to decide what we want jQuery to actually do for us. In this instance, because we have a black and white image sitting directly on top of a colour image, what we want to do is to detect when our mouse hovers over the image (the black and white one, as it's on top) and gradually make it transparent. This will give the image the effect of looking like colour is appearing.

To do this, we have to assign what's called an 'event' to our image. In this case, we want to asign a particular type of event called a 'hover' event. As you may have guessed, this event does stuff when your mouse hovers over whatever the event is asigned to.

This next bit is probably going to look complicated the first few times you see it, but read it over a few times and I have faith you'll understand it.

So, in brief, your webpage is made out of things called DOM objects. Everything on your page pretty much is a DOM object. Images are DOM objects, paragraphs are DOM objects, Divs are DOM objects etc etc. Even the page is a DOM object called 'document'.

jQuery has to look through your page and find the DOM object you want to use, so you have to first tell it what it's looking for. The command to do this is:

jQuery(OBJECT);

where OBJECT is your DOM object. So to find the greyscale image (which is in an  tag with a class of 'a') we say:

jQuery('img.a');

Notice as a side point that all javascript commands have to end with a semi-colon. 

Then we asign the 'hover' event like so:

jQuery('img.a').hover(STUFF1, STUFF2);

Where 'STUFF1' is what we want to happen to the image when we hover over it - and 'STUFF2' is predictably what we want to do when our mouse leaves the image. So now to replace 'STUFF' 1 & 2 with some actuall code for doing things.

Javascript works using things called functions. a function is simply a block of code that does something. 

A function looks like this:

function() { STUFF }

To do stuff inside our hover event we have to write a function that goes inside it.

So:

jQuery('img.a').hover(STUFF1, STUFF2);

becomes:

jQuery('img.a').hover(function() { STUFF1 }, function() { STUFF2 });

Again, STUFF represents what's actually going to happen.

So far this has all been set-up - now onto the fading in-and-out bit. Let's park what we've got already for a moment so we can focus on the animation.

We'll be executing this code inside the hover event of an image, so jQuery already knows what our DOM object is. Therefore, we can refer to our image simply as:

jQuery(this)

And to animate it, we use a jQuery command called:

jQuery(this).animate();

To use .animate() we have to tell it the property we want to manipulate, the value we want it to end up as and how fast we want this all to happen. We do this in the form:

.animate({ 'PROPERTY' : 'VALUE'}, 'SPEED');

So to change the 'opacity' of our image to '0' (0 is transparent, 1 is solid) at a 'slow' pace we do the following:

jQuery(this).animate({ 'opacity' : '0' }, 'slow');

This command will take the image and slowly turn it transparent. But there's one thing we didn't think of yet. A computer can check the page thousands of times a second, and everytime it checks the page while our mouse is over the image, it's going to execute this animation. This is a problem for us, because we only want to execute this code once. To stop the animation firing thousands of times every second, we use the handily named .stop() command.

So now our code looks like this:

jQuery(this).stop().animate({ 'opacity' : '0' }, 'slow');

So, revivng our code from earlier which looked like:

jQuery('img.a').hover(function() { STUFF1 }, function() { STUFF2 });

We can now substitute STUFF1 for what we just wrote

jQuery('img.a').hover(function() { $(this).stop().animate({ 'opacity' : '0' }, 'slow'); }, function() { STUFF2 });

Now, if I've been in any way good at explaining, you'll remember that STUFF2 is what happenes when you stop hovering (i.e when your mouse leaves) over the image. And hopefully you'll have worked out that what we want to do is animate image 'a' back into solidity. So what we do is exactly the reverse of what we did before:

jQuery(this).stop().animate({ 'opacity' : '1' }, 'slow');

We take our image, and slowly set its opacity back to 1 (solid).

Now all we do is substitute this bit of code in for STUFF2, and we get a piece of code looking like this:

jQuery(this).stop().animate({ 'opacity' : '1' }, 'slow');jQuery('img.a').hover(function() { jQuery(this).stop().animate({ 'opacity' : '0'}, 'slow'); }, function() { jQuery(this).stop().animate({ 'opacity' : '1' }, 'slow'); });

This piece of code that we've just built does everything we need it to - well, almost. The final thing we need to worry about is that a wordpress page includes a whole massive heap of javascript and jquery, all trying to execute all at once. And frankly, a lot of that code is a whole heap more important than this code is. So, what we need to do is wrap our ENTIRE code, in one last function.

Now, do you remember that I was talking several hundred words back about DOM objects? and that I said that even the page was an object? Well, now we have to add an event to the whole page! The event we're going to add isnt a 'hover' event, instead, it's a 'Ready' event. The code looks like this:

jQuery(document).ready(function(){ STUFF });

Now, hopefully you'll recognize the layout. The DOM object is the whole web page (or the 'document'), the event is 'ready' - and therefore when the page is ready (i.e. when it has finished doing everything else), the code inside the function will be executed.

So the last step is to put the code all together to get this:

jQuery(document).ready(function(){  jQuery('img.a').hover(function() { jQuery(this).stop().animate({ 'opacity' : '0'}, 'slow'); }, function() { jQuery(this).stop().animate({ 'opacity' : '1' }, 'slow'); }); });

and then ideally make it a bit more readable by putting it on different lines, sticking in some script tags to let the browser know it's javascript and not text, and adding in a few comments:

<script>
//Check webpage has finished loading
jQuery(document).ready(function(){
    //Assign click event
    jQuery('img.a').hover(
        //Animate the fade out
        function() { jQuery(this).stop().animate({ 'opacity' : '0'}, 'slow'); },
        //Animate the fade in
        function() { jQuery(this).stop().animate({ 'opacity' : '1' }, 'slow'); }
    ); 
});
</script>

And with a bit of luck, that should be you! You can copy this into your webpage and it should work straight out of the box.

Good luck! And if you have any follow up questions I promise to try and answer them in much less than a thousand and some words!