jQuery Image Swapping with Fade Effect

Today we are going to cover how to properly change the source of a single image using jQuery. We will also learn how to fade the image out prior to swapping the source, and fade the image back in after the new source has been fully downloaded.

So lets setup a scenario for our script. Lets say we have a bunch of little thumbnails below a larger image. Lets also say our desired functionality here is to have any thumbnail that is clicked on show up as a larger version in the above larger image. Presuming the small thumbnail images have links wrapped around them with a href attribute pointing to the larger version of each thumbnail, we have something to work with.

Demo of scenario in action

To begin, we want to set up new click events for each thumbnails anchor tag and prevent the user from acutely being directed to this image file in the browser.

$('a.thumbnail').click(function(){
    return false;
});

So in the above code we find all anchor elements with a class of “thumbnails” and run over each instance of one. When we find an anchor element that meets this requirement we setup a new click event with an empty anonymous function. Finally in our empty function, we use the “return false;” to prevent the browser from performing the redirect to the image file.

Next we need to gather the clicked anchor tag’s “href” attribute value, and place it into a variable that we will use later on.

$('a.thumbnail').click(function(){
    var src = $(this).attr('href');
    return false;
});

Next, lets prevent from loading images we have already clicked on by comparing our gathered src, to our already set large image’s src, like so:

$('a.thumbnail').click(function(){
    var src = $(this).attr('href');
    if (src != $('img#largeImg').attr('src')) {
    }
    return false;
});

Basically all we are doing is is saying, “If our gathered src is NOT equal to our larger image’s already set ssrc, proceed on to changing the large image’s source”.

Great, now that we have the larger version’s source of our clicked thumbnail, we can proceed on to swapping the image with this new source:

$('a.thumbnail').click(function(){
    var src = $(this).attr('href');
    if (src != $('img#largeImg').attr('src')) {
        $('img#largeImg').stop().animate({opacity:'0'},function(){
                $(this).attr('src',src);
        });
    }
    return false;
});

So here we are pointing the larger image who has and id of “largeImg”, and starting to animate the image’s opacity to 0. Because there is a callback when using jQuery animate, we make use of it to set the source (src=””) of our larger image to our gather thumbnail’s source. We make use of the callback in our animate to prevent the “image source swapping” from happening while the image is still visible.

Next, we want to make sure that our image has fully been downloaded prior to actually making the image indeed visible again. To do this, we make use of the jQuery .load() functionality that will listen to our large image, and perform what we need when the image is ready to be visible.

$('a.thumbnail').click(function(){
    var src = $(this).attr('href');
    if (src != $('img#largeImg').attr('src')) {
        $('img#largeImg').stop().animate({opacity:'0'},function(){
                $(this).attr('src',src);
        }).load(function(){
                $(this).stop().animate({opacity:'1'});
        });
Erectile dysfunction  super viagra online is the inability to obtain erection and perform satisfactorily during sex. It is recommended by the doctor to take this medicine without consult of doctor.Live happy with the sex power enhancing pills have strong chemical composition which usually shows bad sign on health.  buy levitra professional It's considered The World'Strongest sildenafil cost  Antioxidant, and it's totally natural. For instance, if you are buying Sildenafil tablets from Kamagra Tablets, then you can visit their webpage and get all answers for your questions. viagra online heritageihc.com has been really very helpful for women it has proven to be an effective medication and a big success among women facing problems of conception.     }
    return false;
});

So as you can see out last step in the .load() callback functionality is to animate our image back to an opacity of 1 again.

Also, note how I use a .stop() prior to any .animate() call. We make use of .stop() prior to .animate() to prevent the animation fires from collecting if the user clicks our thumbnails rapidly.

So our above code is very compact and meets all our requirements of swapping in larger versions of thumbnail sources while performing a fade effect. Drum roll please….

The Problem:

Erik Kraft helped me reproduce the IE error some people might run into with this method. Apparently because we  are making use of the .load() Ajax feature of jQuery and images, IE has a hard time with caching the requests. Because IE caches the requests, any second attempt to load up an already cached image, fails.

The Solution:

Lucky for us, this is a little fix. The solution is to make all requests unique to IE, so no matter if the request is cached or not our script wont fail. We can make each request unique by appending a random number to the end of our src variable, that then gets evaluated by our .load(). Like so:

$('a.thumbnail').click(function(){
    var src = $(this).attr('href');
    if (src != $('img#largeImg').attr('src')) {
        $('img#largeImg').stop().animate({opacity:'0'},function(){
                $(this).attr('src',src+'?'+Math.floor(Math.random()*(10*100)));
        }).load(function(){
                $(this).stop().animate({opacity:'1'});
        });
    }
    return false;
});

So now our images that will be requested from .load(), will be looking something like this:

img/img-three.jpg?691

My random number is between 1 and 100. This random number gives me a 100 to 1 odds that out of my 4 images, the one I click will be a unique request. I will take those odds sir!

Finally, because we have introduced unique requests into the mix, we have a broken our condition that prevents us from loading images we have already clicked. The reason this breaks is cause we are now trying to compare our large image’s source to a unique version of the same url. We can fix this issue by trimming off our unique number at the end of the images url in our condition statement. Like so:

$('a.thumbnails').each(function(){
    $(this).click(function(){
        var src = $(this).attr('href');
        if (src != $('img#largeImg').attr('src').replace(/\?(.*)/,'')) {
            $('img#largeImg').stop().animate({opacity:'0'},function(){
                    $(this).attr('src',src+'?'+Math.floor(Math.random()*(10*100)));
            }).load(function(){
                    $(this).stop().animate({opacity:'1'});
            });
        }
        return false;
    });
});

And that's it. Enjoy!

Demo of script in action

Devin R. Olsen

Devin R. Olsen

Devin R. Olsen

Located in Portland Oregon. I like to teach, share and dabble deep into the digital dark arts of web and game development.

More Posts

Follow Me:TwitterFacebookGoogle Plus

22 Responses to “jQuery Image Swapping with Fade Effect”

  1. Devin R. Olsen Kate says:

    Hi Devin, thank you this is exactly what I was looking for and is really simple to follow. I’d like to have a script so that the main display image has a link to a larger image but the link will be based on same file extension but instead of ending in -medium.jpg it will say -large.jpg if you can give me some advice, this would be great.

  2. Devin R. Olsen Simcat says:

    Hi ~ thanks so much for this tutorial and explaining it all so it makes sense. I searched far and wide for something like this and finally landed here! Well done.

  3. Devin R. Olsen Jack White says:

    Great script, especially for a non-coder like me, strictly a front-end web designer. I’m just starting the process of spiffing up an old site and thought you’d like to see how I implemented it:
    http://www.judhartmanngallery.com/lacrossegame.html .

  4. Devin R. Olsen Mark says:

    Spencer, did you ever find a solution to your question? I’m also needing to apply a unique ID to each large image and make it click through to a new window with an even-larger image, and am not sure how to do it.

  5. Devin R. Olsen Bud says:

    This helped me accomplish what a web client needed. Thanks Devin!

    2 comments/requests: A way to set transition time would be a nice addition. Also, the first image fades out before the 2nd one loads, which can be visually distracting, depending on the contrast between the images and the background color. A way to adjust the overlap between fades or make the new image finish fading in before the first one starts fading out would be great.

  6. Devin R. Olsen Nik says:

    I have a little problem with this and I have no doubt its probably me.

    The code fades out the big image but DOES NOT fade in the sub image that was clicked. I was wondering if you had a clue as to what it is I have done wrong? All file paths are correct and have been checked several times.

    I’m using the method without the IE fix. I’ve tried it with as well. Which didn’t solve my problem.

    All in all I’ve checked dozens of sites and yours is the best by far so I’d like to keep at it. Any advice would be great.

    Thanks

  7. Devin R. Olsen Mark says:

    Does it matter that I’m using a newer version of jQuery?

    Does it matter what the div id’s are that the images are in?

    Thanks!

  8. Devin R. Olsen Kyle says:

    Any way to make it faster?

  9. Devin R. Olsen Jez says:

    Great tutorial!

    It would be nice to have a ‘loading’ message or animated gif while the large image is loading.

  10. Devin R. Olsen james says:

    nice and easy solution :)
    it is possible to image swap automatically??

  11. Devin R. Olsen Spencer says:

    Fantastic solution, got it working within minutes! Easiest jQuery tutorial i have ever found, well done Devin!

    A quick question, how would i add a unique link to the large image and pass on the new link once a thumbnail has been clicked, my design requires the large image to open up a larger version in either prettyphoto or simply open up a new page displaying a hires version.

  12. Devin R. Olsen c.harford says:

    To make the image swap on hover (mouseover) I just changed this line:
    $(this).click(function(){
    to this:
    $(this).hover(function(){
    and the hover swap works really well!

    Tested on Windows 7 64bit
    – Chrome 14.0.835.187
    – FF 6
    – IE 9 (64bit)

  13. Devin R. Olsen c.harford says:

    Is it possible to make the image swap work on hover?

  14. Devin R. Olsen Ono Sendai says:

    Hello,

    Your script is great but I was wondering if it would be possible to make it ignore empty links so that it keeps the last displayed image instead of replacing it with a blank one.

    Have no idea how to accomplish that, if you could help me out I’d be very thankful.

    Thnx!

  15. Devin R. Olsen John says:

    this is great, I’ve been looking for something like this for a while.

    the way you’ve explained it is really easy to understand

    thanx

    is it possible to change a ‘background’ image detailed in CSS? by amending $(‘img#largeImg’)

  16. Devin R. Olsen Allen Snook says:

    Works wonderfully – thank you for sharing this jQuery goodie!

  17. Devin R. Olsen eric says:

    Hi, i think it is not good to load the large picture every time,even if it has been cached by the browser. We should add a conditon to see wether the large imgage has been cached or not.It will save a lot of time.

  18. Devin R. Olsen kurius says:

    Very new to JS and finding JQuery.
    Coming from as though, so I foresee a smooth transition (hopefully -_^ ).
    I have a question though, I noticed that if you click a thumb and the larger version loads in, when you click the thumb again, it fades out but doesn’t get replaced. Is there a reason it can’t replace itself?
    Thanks and Very nice, concise, snippet of code here!!

    • @kurius – Yes, this is an issue. I have updated the tutorial and code to carry a simple condition to test if the clicked image is already loaded or not to prevent this.

      Thanks!

  19. Devin R. Olsen Mehmet says:

    Nice! Talk about keeping it simple and giving a great effect.

  20. I always enjoy feedback from my readers.

Leave a Reply