Photo Gallery – jQuery Film Strip
As previously detailed the Photo Gallery utilizes a film strip on the left and a high resolution view in the center. The previous implementation showed all the thumbnails in a vertical film strip that could be scrolled. The high resolution image used a “position: fixed” CSS attribute to keep always in view.
During this phase of the Photo Gallery I am experimenting with the power of jQuery by implementing new features. The feature detailed in this article is a “sliding film strip”. I wanted to implement a film strip like the one by Michael Leigeber shown here. I had already implemented the fade effect on mouse over previously. The thing that I was most interested were the behavior of the two buttons.
The final film strip is shown here to the left. The content that you see is the film strip and two buttons. The two buttons scroll the film strip up or down. As I will show, the trick to getting this effect relies on what you don’t see.
The html for this content is show here:
<div id="thumbnails"> <div id="slidetop" title="scroll"></div> <div id="slidearea"> <div id="slider" style="top:0px;"> <div id="_divOuterThumbs"> loading... </div> </div> </div> <div id="slidebot" title="scroll"></div> </div>
The film strip content is loaded dynamically using AJAX to replace the content of the “_divOuterThumbs” div. The CSS that styles these elements is shown here:
#slidetop { background: #333333 url(images/scroll-top.png) no-repeat scroll center center; height: 20px; width: 138px; } #slidearea { height: 560px; width: 140px; overflow: hidden; position: relative; } #slider { position: absolute; height: 560px; } #_divOuterThumbs { } #slidebot { background: #333333 url(images/scroll-bot.png) no-repeat scroll center center; height: 20px; width: 138px; }
The “trick” is in the style of the “slidearea” div. The overflow attribute of that div is set to hidden. This clips the visible content of all its children to only what can be seen in the 140px by 560px area. Although many more thumbnails can be loaded into the “_divOuterThumbs” div, only the ones that fit in this window can be seen.
To get the “up” and “down” button to work requires some JavaScript to dynamically adjust the “top” attribute of the “slider” div. Before divulging this JavaScript notice that the “sliderarea” div has a position attribute set to relative. This allows any value specified in the “top” attribute to be relative to its normal position. So setting a style of “top: 0px;” positions this div in its normal position. A setting of “top: –10px” would position this div 10 pixels above its normal position. This would have the appearance of the film strip being scrolled up. The other key style is the position attribute of the “slider” div has been set to absolute. This allows it and all its children to be positioned at the specified coordinates relative to its containing block (“slidearea”).
The following code contains all the JavaScript that is used to connect up the events to achieve the desired behavior:
// Create my namespace. var slider = {}; // Intialize the slider control slider.init = function(topButtonDivId, botButtonDivId, sliderDivId) { slider.topButSel = "#" + topButtonDivId; slider.botButSel = "#" + botButtonDivId; slider.sliderSel = "#" + sliderDivId; slider.top = 0; slider.height = 0; slider.slideIntervalId = undefined; $(slider.topButSel).hover( function() { $(this).css("background-color", "#555555"); slider.slideIntervalId = setInterval( function(){slider.slide(3);}, 20); }, function() { $(this).css("background-color", "#333333"); if(slider.slideIntervalId!=undefined) { clearInterval(slider.slideIntervalId); slider.slideIntervalId = undefined; } } ); $(slider.botButSel).hover( function() { $(this).css("background-color", "#555555"); slider.slideIntervalId = setInterval( function(){slider.slide(-3);}, 20); }, function() { $(this).css("background-color", "#333333"); if(slider.slideIntervalId!=undefined) { clearInterval(slider.slideIntervalId); slider.slideIntervalId = undefined; } } ); $(slider.sliderSel).mousewheel(function(event, delta) { slider.slide(30*delta); }); } // Slide the element slider.slide = function(amount) { slider.top += amount; if(slider.top>0) { slider.top = 0; if(slider.slideIntervalid!=undefined) { clearInterval(slider.slideIntervalId); slider.slideIntervalid = undefined; } } else if(slider.top<slider.height) { slider.top = slider.height; if(slider.slideIntervalid!=undefined) { clearInterval(slider.slideIntervalId); slider.slideIntervalid = undefined; } } $(slider.sliderSel).css("top", slider.top + "px").show(); } // Move the element to the top slider.moveTop = function() { slider.top = 0; $(slider.sliderSel).css("top", slider.top + "px").show(); } // Set the slider length slider.setSlideLength = function(length) { slider.height = length; }
I placed all this code in its own namespace and encapsulated it with its own class. This class utilized jQuery to simplify the JavaScript. Most importantly jQuery makes it much easier to provide a cross-browser implementation of your code.
The init function does the following:
- Takes as parameters the element id’s that define the div for the two buttons and the slider.
- It converts these id’s into jQuery selectors and stores them in local variables.
- It then initializes some additional local variables:
- top = initial top of the slider element = 0 – This is used to position the slider and create the scrolling effect.
- height = height of the slider element = 0 – This sets the slide length and is used as bounds checking when scrolling. This height prevents the user from scrolling beyond the last thumbnail.
- slideIntervalId = the id associated with the setInterval function = undefined – This is used to cancel the setInterval callback.
- It connects up the “up” and “down” buttons. This done using the jQuery hover function.
- The hover on callback, changes the background color a bit to add a visual effect and then starts the scrolling by using the setInterval JavaScript function. This function is set to call the callback every 20 milliseconds. The two buttons are wired up nearly the same, with the only exception being the parameter to the “slider.slide” function. This parameter has the opposite sign in the two cases. The sign of this parameter determines if the slider div is scrolled up or down.
- The hover out callback, resets the background color and then stops the setInterval callback from occurring any more.
- I like to use my mouse scroll wheel. So this next thing that is connected up is a mousewheel event. This functionality is provided by a jQuery plug-in created by Brandon Aaron that can be found here. This event simply results in another mechanism for the slider.slide function to be called.
The sliding takes place in the slider.slide function. This function adjusts the “top” attribute by the amount passed into the function parameter. It then validates that this new position doesn’t scroll the slider beyond the allowed end points. If the new position is determined to be not valid, then the end point is adjusted and any setInterval callback is cancelled. The last statement in that function uses jQuery to set the “top” attribute of the slider div.
The other two function provide methods to reset the top and length of the slider div. These are used when ever a new film strip of thumbnails is loaded into the slider div. The slider.moveTop function removes any previous scrolling. The slider.setSlideLength function sets the new allowed slide length.
A live version of the Photo Gallery demonstrating this scrolling can be found here.