jQuery Swapping Portfolio
Here’s a demo of everything I’m about to discuss.
Recently, a number of clients have asked for an complex dynamic image-gallery-like page for a few different applications like portfolios and staff directories. The CMS I work with allows me to build a complex page for the client to load up with content, but the front end is where all the magic happens.
The first of these sites featured an artistic design and required a portfolio for landscape projects, so I wanted to go with an elegant flowing effect. There are two primary element to this concept: the navigation and the content. The content itself can be further divided to images and text, both of which are important elements for this particular layout.
The navigation consits of two columns of thumbnails down the side (or wherever you need them – for this example they’re on the side). They live in a div that’s floated to the right. Here’s what that code looks like:
Each thumbnail is tied to a div which is given a different ID. (link_1, link_2, etc.). In the script, we bind each of those IDs to a click event:
$('#link_1').bind('click', {id:'1'} ,clickHandler);
$('#link_2').bind('click', {id:'2'} ,clickHandler);
etc.
When anything in that div is clicked, it fires the click event, aptly named clickHandler:
var clickHandler = function(link){
$('.main').fadeOut().pause(250);
$('#content').animate({"height": $('#main_' + link.data.id).height() + 20}, {duration: "slow"});
$('#main_' + link.data.id).pause(250).fadeIn("slow");
}
Important safety tip: That pause() function is there to slow things down so fadeouts don’t cross:
$.fn.pause = function(duration) {
$(this).animate({ dummy: 1 }, duration);
return this;
};
Now, on the content side, it’s just a matter of stacking up DIVs with your content in them and giving each div a unique (and patterned with the same id structure as your thumbnail IDs) ID (main_1, main_2, etc.). Granted, if you’ve got a lot of data, you’re probably better off with a system to import it via AJAX, but for this instance, we’re going to cover a smaller data set.
So, we’ve got our sidebar:
<div id="sidebar"> <div id="link_1"><img src="images/thumb_1.jpg" alt="" /></div> <div id="link_2"><img src="images/thumb_1.jpg" alt="" /></div> </div>
And we have our content:
<div id="content"> <div id="main_1" class="content_div">Content div 1</div> <div id="main_2" class="content_div">Content div 2</div> </div>
Now we just need a little styling on the content divs to hide them:
.content_div { display:none; }
Then it’s just a matter of displaying your first div when the page loads:
$(window).load(function(){
$('#content').animate({"height": $('#main_1').height() + 20}, {duration: "slow"});
$('#main_1').pause(250).fadeIn("slow");
});
The $(window).load call is important. You don’t want this to fire right on (document).ready if there are any images in your first div, because they will likely not be completely loaded and the code won’t know how big that div is going to be.
so, here’s the simple code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
#sidebar { width:230px; float:left; }
#sidebar div { float:left; margin-left:5px; }
#content { width:500px; float:left; }
.content_div { display:none; }
</style>
<script language="javascript" type="text/javascript" src="js/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
<!--
$(document).ready(function(){
$.fn.pause = function(duration) {
$(this).animate({ dummy: 1 }, duration);
return this;
};
var clickHandler = function(link){
$('.content_div').fadeOut().pause(250);
$('#content').animate({"height": $('#main_' + link.data.id).height() + 20}, {duration: "slow"});
$('#main_' + link.data.id).pause(250).fadeIn("slow");
}
$(window).load(function(){
$('#content').animate({"height": $('#main_1').height() + 20}, {duration: "slow"});
$('#main_1').pause(250).fadeIn("slow");
});
$('#link_1').bind('click', {id:'1'} ,clickHandler);
$('#link_2').bind('click', {id:'2'} ,clickHandler);
});
-->
</script>
</head>
<body id="top">
<div id="sidebar">
<div id="link_1"><img src="images/thumbnail.jpg" alt="" /></div>
<div id="link_2"><img src="images/thumbnail.jpg" alt="" /></div>
</div>
<div id="content">
<div id="main_1" class="content_div">Content div 1</div>
<div id="main_2" class="content_div">Content div 2</div>
</div>
</body>
</html>