jQuery fading and sliding image gallery

Mar4th
2008
••

jQuery Gallery

The idea was raised by a collegue how to go about recreating something similar to The New York Times The Little Rock Nine: 50 Years Later flash feature without using flash. In my “infinite wisdom” I said something along the lines of,“no problem, jQuery and CSS can do all that”. Good going Alan. After a few days on and off fiddling with it, I may have come across a decent substitute.

My idea began trying to combine the article on jQuery “slicker show and hide” and Apple™ style slider gallery. From there I had to add other effects to the mix so I dug into the jQuery cycle plugin. Those three combined with a little edits and a lot of reading and trial and error, brought me a nice gallery. Take a look at the demo.

This next part is my modifications to my gallery.js file.

Well the first thing I needed to do was make the scroller go vertical instead of horizontal. Modifying the slider code I came up with this:

var container = $('div.sliderGallery');
var ul = $('ul', container);
var itemsHeight = ul.innerHeight() - container.outerHeight();
    $('.slider', container).slider({
         minValue: 0,
        maxValue: itemsHeight,
        handle: '.handle',
        stop: function (event, ui) {
             ul.animate({'top' : ui.value * -1}, 500);
           },
       slide: function (event, ui) {
           ul.css('top', ui.value * -1);
        }
});

Essentially changing any reference of Width to Height and any left to top. That seems to make things work. The only issues I’m having, that I noticed, with the slider come in Opera and Safari. In Opera, when you let go of the scrollbar, it loses functionality. You can still click, but you can’t grab. I think this might be in the ui.mouse.js or the ui.slider.js rather than in the little bit of code here. In Safari the dragging is choppy. Not a huge issue and doesn’t break functionality.

// fade page in

$('#load').hide();
$('#load2').fadeTo(2500, 1, function () {
     $('#load2').fadeOut(700, function() {
          $('#cover').fadeTo(1000, 0);
          $('#cover').hide(400);
     });
});

Now I’m getting fancy. #load is the image loader gif so I want it to hide. Then I want the circular page loading gif to fade in. In this case in 2½ seconds it fades form transparent to fully opaque then starts a function. It fades out in .7 seconds and starts yet another function that fades out my #cover (all that is is a whiite div that covers the whole page), and after 1 second hides the ##cover. Hiding it is essential because if it’s still there but transparent, you can see what’s underneath but it’s all unclickable. That simultes the page loading effect.

This section tells the first list element to have the active state and load up the first box.

// this sets the first li and the first slickbox as 'on' at load

$('.items li').eq(0).addClass('active');
$('#load').fadeIn(800);
$('#load').fadeTo(800, 1);
$('#load').fadeOut(800, function() {
    $('.slickbox').eq(0).fadeIn(800);
    $('span').css('opacity', '1');
    $('.slickbox').eq(0).prepend('<div class="nav">');
    $('.z1').eq(0)
        .cycle({
        fx: 'fade',
        speed:  500,
        timeout: 0,
        pager: '.nav'
        });
});

Since count starts at 0, the eq:(0) tells jQuery to find the very first of each of these elements. in the following section I’ll explain what all this is doing as they are very similar. The above is just specifically calling the first instances.

This part took me the longest to figure out.

// fade and toggle boxes and content

$(".items li").each(function (i){
    $('.slickbox').hide();
    $('#load').hide();
    var $match = $('.slickbox').eq(i);
    var $match2 = $('.z1').eq(i);
    $(this).click(
        function (){
        $('.nav').remove();
        $('.slickbox').fadeOut(200, 0);
        $('#load').fadeIn(800);
        $('#load').fadeTo(800, 1);
        $('#load').fadeOut(800, function() {
            $match.fadeIn(800);
            $('span').css('opacity', '1');
            $match.prepend('<div class="nav">');
            $match2
            // commented to try out 'prepend' method
            //.before('<div class="nav">')
                .cycle({
                fx: 'fade',
                speed:  500,
                timeout: 0,
                pager: '.nav'
                });
            });
        }
    )
});

I take each ,items li in the document and apply a function to them. I want to hide all my .slickbox divs and the image loading gif. The I set up some variables. $match is equal to each .slickbox in order as they come in the document. $match2 is every .z1 in order. $(this).click applies to each list item and starts another functon. $(’.nav’).remove() is real important. Without it, everytime the same list item is clicked it adds another .nav, not good. A second clicks adds one and so on. Doing this confuses the script and makes all the links unclickable, so I want to remove any instance of it from the code. Now I want to fade out any existing .slickbox. If it’s the first time you click it doesn’t do anything but this keeps multiple boxes from over lapping on the screen. Now my image loading gif fades in then stays on the screen for 1 second then fades out and fires yet another function. $match(i) fades in. The i will be the number in order as it is in the document and will be the same number as the list you click. So clicking the third list item on the page loads the third box on the page. The next line, $(’span’).css(’opacity’, ‘1′); is again very important. It took me a wile to figure out why it was not working right.

The situation was that when you first clicked on a list item, it worked fine. At anytime, if you clicked ona previously clicked list item, the first image was not loading. Using Aardvark, I could tell the span and the iamge was actually loading but they were staying transparent. What the previous line does is manually resests the span to opaque. It seems jQuery doesn’t do this, or doesn’t do this with this release.

Then I start the clycle plugin to set up a pager and make the contents of the span act as a gallery.

The last of this is the easiest part really. Adding and removing classes on the list items as they are clicked and/or hovered over.

// add-remove class on lists
$(".items li").addClass('notactive');
$('.items li').click(function() {
    $(this).addClass('active');
    if ($(this).is('active')) {
        $(this).removeClass('active');
    } else {
        $('.items li').removeClass('active');
        $(this).addClass('active');
    }
});

// hover the lists

$('.items li').hover(function() {
    $(this).addClass('activeh');
    }, function() {
        $(this).removeClass('activeh');
    });

// remove border onfocus

$('.items li').click(function() {
    $(this).removeClass('activeh');
});

The removing the border on focus is not needed actually. At first I had links over the whole list item and the border was causing visual issues.

The HTML is really straight forward. The CSS is a little messy as you have to define and redefine classes being set and removed by jQuery. Since this was an experiement in jQuery I’m not going to go into too much detail about either. The one thing that will be a factor if you use this is that my example has a fixed height and width. This make the images in the gallery have to be a max height or width as well. A lot of absolute positioning is also used so take special care when altering the CSS. There are some elements that have background colors applied to them, namely the span and h2 of the ul.items. This has to be set in order to fix the font rendering bug in IE6. There is also a bug I’ve only noticed in IE6. When you hover over a non-active list item, it removes the border. I think chaining three classes in the css freaks IE6 out. I might have to look into applying the border change via javascript.

Special thanks go out to:

Known issues

  1. .handle “locking” in Opera
  2. notactive hover mis-handling the class addition in IE6

Futre possible additions

  1. Make the slider scale depending on the maxvalue of the UL
  2. make a height variable and add the slider spans height trough jQuery.
  3. Make loading of one box die if another list item is clicked.

*Note: This is just a test for my learning. It is not supposed to work without javascript enabled. I did not go through the steps to make it do so as I am learning jQuery first. If at some point I want to implement this gallery, I will try and find a suitable non-javascript alternative as well.

Tags: ,
Posted in: jQuery
You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.
*hint: If you liked this post you can always show some link love. Digg  del.icio.us  StumbleUpon  Reddit  Design Float  TwitThis 

23 Comments

  1. May1st
    2008
    ••

    Licht

    Demo looks nice.

  2. Aug12th
    2008
    ••

    Dustin

    Great demo - thank you. One question — when the number of images within each “Gallery” exceeds 10 (I should say 12 to be more definite) the excess are not displayed by the page. I am looking into a “safe-guard” to wrap into the jQuery call that would go to “next line” or “additional” in another area. If you have any ideas please let me know.

  3. Jun6th
    2009
    ••

    accounting homework

    Good one, galleries can be useful at times especially for projects etc

    Thanks for posting them :)

  4. Jun22nd
    2009
    ••

    Accounting Homework

    Very Good,,,
    Your article very good and good gallery .I will add you as a topic .Give me another information.

    Thanks.

  5. Jun30th
    2009
    ••

    reiki

    Excellent information. Finding a few such solutions has taken hours in the past.

    Thank u.

  6. Nov22nd
    2009
    ••

    farmville cheats

    Em, your site is too dark, i don’t this color.

  7. Dec18th
    2009
    ••

    srk

    good one but then not working properly with chrome when we try to scroll down the scroller, its not going back up. can u please fix the issue??

  8. Feb13th
    2010
    ••

    German

    The scroll and the buttons up and down doesn’t work on my browsers (safari & firefox), do you have any idea why it could be?

  9. Feb20th
    2010
    ••

    neel

    Excellent gallery … i used and works perfect.. thanks for sharing….

  10. May27th
    2010
    ••

    strainers

    Nice post…..

  11. May27th
    2010
    ••

    gem

    Thnk for info

  12. May27th
    2010
    ••

    diip

    nice post…Thank you

  13. May27th
    2010
    ••

    Holistic

    good article. . Thank you for posting

  14. Jun30th
    2010
    ••

    jeba

    Thanks for posting good collection

  15. Jun30th
    2010
    ••

    raashi

    Good and Amazing collection

  16. Oct4th
    2010
    ••

    Office chairs chennai

    Its great collection..its useful..Thanks for sharing

  17. Nov9th
    2010
    ••

    Farmville

    wow, thanks for sharing the code.

  18. Nov9th
    2010
    ••

    Earn

    Thanks for sharing. The coding is impressive!

  19. Nov9th
    2010
    ••

    Death Knight Guide

    I am still new at CSS.

  20. Dec10th
    2010
    ••

    pribeiro

    I wanted to use it in my website but it won’t work with jQuery latest version :( and I can’t use two versions of jQuery in my website.

  21. Dec10th
    2010
    ••

    pribeiro

    anyway you can solve this?! I’m new with jQuery…

  22. Dec19th
    2011
    ••

    emmster

    hi - is this still being developed or has it dropped off your radar?

    thanks,
    emm

  23. Mar27th
    2012
    ••

    falseflooring

    Thanks for sharing the great idia.