Shadowbox Mods - Thumbnails in overlay - Basic version

- by Peter Mitchell

All modifications are based on the original Shadowbox code by Michael Jackson which can be downloaded from the Shadowbox website.

History

In the past I'd been using Lightbox and later Litebox for my image viewing needs. They're both great but I'd never been too keen on the default navigation style, I always wanted thumbnail images in the lightbox itself which would allow me to switch the main image. I was also starting to get into JQuery in a big way, so when I went looking for a replacement I consulted the Lightbox clone comparison matrix and found Shadowbox (which was at version 2 at that point in time). While it doesn't offer the option of thumbnail navigation as standard I'd noticed this post on the support forum which seemed to suggest that it was possible (thanks to Micke04 and Wizzud for lighting the way). After a bit of hacking about with the code I got the thumbnail functionality working. I was aware that the code was a bit messy and I'd always intended to revisit it at some point and clean it up, but never quite got round to it. With the release of Shadowbox 3 with support for IE8 I thought it would be a good time to go back and take another look, only this time I'd try to keep the code clean and document my modifications as I went along, for my own benefit and the benefit of anyone else who's interested, hence the reason these pages are here.

Explanation

This is my first attempt at putting thumbnails into the Shadowbox. At the moment I'm just trying to add the minimum code required to add the thumbnail feature without sacrificing any of the existing functionality. This is probably going to highlight a few problems but will give me a standard code base for further exploration.

Pros

  • You get thumbnails in the overlay window!
  • All the standard functionality still works (as far as I can tell).

Cons

  • Large gallery navigation doesn't seem very intuitive (see the example on the left).
  • Very dependant on the image sizes/browser window size for the navigation to display properly.

Download

Get the source code. This only contains the modified versions of shadowbox.js and shadowbox.css so you'll still need a full working copy of Shadowbox 3.

If you have any questions about the modified code please add them to this post on the Shadowbox support forum.

Changes to code

Original Shadowbox code appears first with the blue background, modified code follows with a yellow background and changes highlighted in red.

All changes shown here are based on Shadowbox 3.0rc1

Changes to shadowbox.js

This is basically just going to be a modified version of the skip style counter with thumbnail images instead of numbers. Since I want to maintain all the existing functionality of Shadowbox I'm going to add a new counterType called 'thumbskip' and set it as my default. I'm also dropping the counterLimit to 7 since that's what fits comfortably with the thumbnail size I'm using. Here's how the code looks to start with...

counterLimit: 10, // limit to the number of counter links that // are displayed in a "skip" style counter counterType: 'default', // counter type. May be either "default" or // "skip". Skip counter displays a link for // each item in gallery

...and this is what I'm going to change it to:

counterLimit: 7, // limit to the number of counter links that // are displayed in a "skip" style counter counterType: 'thumbskip', // counter type. May be either "default", // "skip" or "thumbskip". Skip counter displays // a link for each item in gallery. Thumbskip // adds a thumbnail.

If you don't want to set these as your defaults they can just as easily be passed in as parameters for specific shadowbox instances.

I'm going to need to extract the thumbnails src attribute to use when building the counter so I'll start with the buildCacheObj function. Here's what it looks like as standard:

buildCacheObj: function(link, opts){ obj = { el: link, title: link.getAttribute('title'), options: apply({}, opts || {}), content: link.href // don't use getAttribute here };

Changes to the code are highlighted in red. I'm assuming the thumbnail is the first child of the link and adding it's src attribute to the obj array.

buildCacheObj: function(link, opts){ obj = { el: link, title: link.getAttribute('title'), options: apply({}, opts || {}), content: link.href, // don't use getAttribute here source: link.firstChild.src // add the thumbnail src };

Next I'll look at how the counter is built.

// build the counter var counter = ''; if(S.options.displayCounter && S.gallery.length > 1){ var len = S.gallery.length; if(S.options.counterType == 'skip'){ // limit the counter? var i = 0, end = len, limit = parseInt(S.options.counterLimit) || 0; if(limit < len && limit > 2){ // support large galleries var h = Math.floor(limit / 2); i = S.current - h; if(i < 0) i += len; end = S.current + (limit - h); if(end > len) end -= len; } while(i != end){ if(i == len) i = 0; counter += '<a onclick="Shadowbox.change(' + i + ');"' if(i == S.current) counter += ' class="sb-counter-current"'; counter += '>' + (i++) + '</a>'; } } else var counter = (S.current + 1) + ' ' + S.lang.of + ' ' + len; }

This follows one of two paths depending on whether it's a skip style counter or the default style. The skip style counter also has some useful logic built in that creates a wraparound counter if the number of images exceeds the limit specified by the counterLimit variable. By branching the thumbnail counter code from the existing skip code I can retain that functionality.

// build the counter var counter = ''; if(S.options.displayCounter && S.gallery.length > 1){ var len = S.gallery.length; if(S.options.counterType == 'skip' || S.options.counterType == 'thumbskip'){ // limit the counter? var i = 0, end = len, limit = parseInt(S.options.counterLimit) || 0; if(limit < len && limit > 2){ // support large galleries var h = Math.floor(limit / 2); i = S.current - h; if(i < 0) i += len; end = S.current + (limit - h); if(end > len) end -= len; } if(S.options.counterType == 'thumbskip') { // thumbskip counter while(i != end){ if(i == len) i = 0; counter += '<a onclick="Shadowbox.change(' + i + ');"' if(i == S.current) counter += ' class="sb-counter-current"'; counter += '>' + '<img src="' + S.gallery[(i++)].source + '" />' + '</a>'; } } else // skip counter while(i != end){ if(i == len) i = 0; counter += '<a onclick="Shadowbox.change(' + i + ');"' if(i == S.current) counter += ' class="sb-counter-current"'; counter += '>' + (i++) + '</a>'; } } else var counter = (S.current + 1) + ' ' + S.lang.of + ' ' + len; }

The standard skip counter is built by outputting a series of links with onclick handlers that call the change function. The modified version for the thumbskip counter just replaces the text in the links with the thumbnail images that were added to the obj array previously.

And that's all the changes to the javascript done.

Changes to shadowbox.css

As with the javascript I'm keeping the changes to the CSS to the minimum required to get the job done. The first step is to increase the height of the sb-info and sb-info-inner divs to accomodate the thumbnails. The exact height required will depend on the size of the thumbnail images and the amount of vertical space around them but in this case a value of 56px gives the desired result.

#sb-info, #sb-info-inner { height: 56px; }

Next I'll drop the width of the sb-nav div since I'm going to need the extra space to accomodate the thumbnail counter.

#sb-nav { float: right; height: 16px; padding: 2px 0; width: 19%; }

And finally I'll increase the width of the sb-counter div and add borders and :hover classes to the thumbnails to improve things visually (Note: The :hover pseudo classes don't work in IE6 or IE7 for some reason, see this post on the Shadowbox support forum for further details).

#sb-counter { float: left; padding: 4px 0 0 0; width: 80%; } #sb-counter a { padding: 0 4px 0 0; text-decoration: none; cursor: pointer; color: #fff; } #sb-counter a.sb-counter-current { text-decoration: underline; } #sb-counter a img { border: solid 1px #000; } #sb-counter a:hover img { border-color: #0f0; } #sb-counter a.sb-counter-current img, #sb-counter a.sb-counter-current:hover img { border-color: #fff; cursor: default; }

And that's it, thumbnail navigation in the Shadowbox. As I've mentioned, I don't think the navigation of large galleries seems very intuitive and could become an issue if the gallery contained narrow images that would cause the counter to get cut off, but that's something I'll look at later.

Examples

counterType = 'thumbskip'

Small Gallery
Autumn Leaves Creek Desert Landscape Dock Forest Forest Flowers
Large Gallery
Autumn Leaves Creek Desert Landscape Dock Forest Forest Flowers Frangipani Flowers Garden Green Sea Turtle Humpback Whale Oryx Antelope Toco Toucan Tree Waterfall WinterLeaves
Product style gallery

The first thumbnail image is hidden using CSS and the gallery is activated from an onclick handler on the bigger image.

Autumn Leaves
Autumn Leaves Creek Desert Landscape Dock Forest Forest Flowers
Small Images

This is just to show how the navigation can 'break' if the linked image isn't wide enough.

Autumn Leaves Creek Desert Landscape Dock Forest Forest Flowers
YouTube & Vimeo
Star Wars Gangsta Rap SE Cai...Cai...Pyramids!!! Bloodthirsty

Control Tests

Just to check that the standard functionality is not affected by changes

counterType = 'default'

Autumn Leaves Creek Desert Landscape Dock Forest Forest Flowers

counterType = 'skip'

Autumn Leaves Creek Desert Landscape Dock Forest Forest Flowers

counterType = 'skip' no thumbs

1 2 3 4 5 6