Creating a simple sliding navigation with jQuery

Posted on Friday, October 30th, 2009 at 9:12 am

As we know, jQuery not only makes things once considered impossible on the web possible, but makes those things pretty easy to do. I just built a sliding navigation for pukkared.com portfolio and thought I’d share here. Pulling this off requires both CSS and javascript knowledge. I’ll do my best to explain the CSS involved, but maybe Adri can follow up on this post with some more detail on why it works. I’ll also note that practically this navigation would be dynamically driven, but for the sake of simplicity I’m going to hard code the navigation. Maybe I’ll follow this up with a post on outputting your navigation from your database.

Main HTML Page

<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />
<title>Untitled Document</title>
</head>
<body>
<!–this is our mask–>
<div id=”content_container”>
<!–this moves the content back (‘L’ for Left)–>
<div id=”previous_id”>L</div>
<!–this div will move to the left and right (as well as the content inside)–>
<div id=”scroll_id”>
<!–list of contents–>
<div id=”content_one”>Content One</div>
<div id=”content_two”>Content Two</div>
<div id=”content_three”>Content Three</div>
<div id=”content_four”>Content Four</div>
<div id=”content_five”>Content Five</div>
<div id=”content_six”>Content Six</div>
<div id=”content_seven”>Content Seven</div>
</div>
<!–this moves the content forward (‘R’ for Right)–>
<div id=”next_id”>R</div>
</div>

For the HTML we need three main elements. A wrapper which serves as a mask, buttons to slide the content left and right, a container to hold the data that gets moved back and forth, and the content itself. In order to make this look a little more legible when we test it in a browser let’s add some oh so crucial CSS.

Main Page CSS

<style type=”text/css”>
#content_container {
float: left;
width: 800px;
margin-top: 10px;
position: relative;
clear: both;
height: 100px;
overflow: hidden;
}
#previous_id {
display: block;
height: 100px;
width: 25px;
float: left;
position: absolute;
left: 0px;
top: 0px;
z-index: 1000;
}
#next_id {
display: block;
height: 100px;
width: 25px;
float: left;
position: absolute;
left: 775px;
top: 0px;
z-index: 1000;
}
#scroll_id {
width: 2000px;
position: absolute;
left: 25px;
top: 0px;
height: 100px;
float: left;
z-index: 500;
}
.content {
width: 100px;
padding-left: 25px;
padding-right: 25px;
float: left;
}
</style>

This CSS can be placed in the header of your file, or put in an external file and linked to.  A few crucial things to note here about the CSS is the use of positioning,  display, and the z-index.  The rest of the properties here can be adapted to suit the style of your particular application.  So first is positioning.  The main thing that we want to do is make sure that our mask (content_container) has a position set to relative, and that our three containers (previous button, next button, and scroll container) all have a position set to absolute.  This allows us to layer our divs here.  We need this so that when the container goes outside of the mask we no longer see it.  Which brings me to the overflow.  Set the overflow rule to hidden for the mask (content_container).  This will hide any data that spills over the edge of our mask.  And lastly, the z-index makes sure that our layers are in the right order.  We want to make sure that our scroll container goes behind the mask.  This will occur as long as the  over flow is set to hidden and the scroll container is positioned relative to the mask.  What does need to be specified here though is the z-index of the left and right buttons in relation to the scroll container.  The reason is because if the scroll container is on top of the left and right buttons, they will not be clickable when the container moves over the top.  So to fix this give the scroll container a smaller z-index value than the left and right buttons.

Bringing it all together (the jQuery)

$(document).ready(function()
{
//set the scroller width
var scrollWidth = 1050;  //this is the width of each item (including padding) * the number of items

//run our functions initially when the page loads.  Pass the scrollwidth to each
checkPosition(scrollWidth);
slideLeft(scrollWidth);
slideRight(scrollWidth);
});

checkPosition = function(scrollW)
{
//get the x position of the scroll div. This will determine whetehr or not to show the right or left arrow button
var xValue = $(“#scroll_id”).position();
//get the value of  the x position of our scroll container, multiply it by -1 to convert it to a positive
//(the xValue is negative to start), and then add back the 25 pixels of padding we use
var xValue = ((xValue.left – scrollW ) * -1) + 25;

if(xValue <= scrollW)  //check if we should show the previous button
{
//hide the button
$(“#previous_id”).hide();
}
else  //check if we should show the next button
{
//show the button
$(“#previous_id”).show();
};

//determine whether or not to show the right arrow button (this is the width our data minus 5 since we don’t want to exceed our last view.)
if(xValue > scrollW)
{
//hide the button
$(“#next_id”).hide();
}
else
{
//show the button
$(“#next_id”).show();
}
}

slideRight = function(scrollW)
{
//animate the scroll div to the right
$(“#next_id”).click(function()
{
$(“#scroll_id”).animate({left: “-=750px”}, 1000, function()
{
checkPosition(scrollW);
});
});
}

slideLeft = function(scrollW)
{
//animate the scroll div to the right
$(“#previous_id”).click(function()
{
$(“#scroll_id”).animate({left: “+=750px”}, 1000, function()
{
checkPosition(scrollW);
});
});
}

There’s a little bit going on here.  The first thing we need to do is get the overall width of our scroll container.  We set this width to 2000 pixels in the CSS to give us plenty of space.  But here we need to know how much horizontal space is our content taking up.  So each piece of content is 100 pixels wide with 25 pixels of padding on each side making it 150 pixels wide in total.  We have 7 of these, so our total content is 1050 pixels.  Then we initialize our main functions.  All of this occurs in jquery’s document.ready function.

Only two things are left to be done.  One is determine when to show the left and right button, and two make the scroll container move to the left and right when needed.  When the slider is at the beginning we don’t need to show the previous button, and when it is at the end we do not need to show the next button.  We need to use jQuery’s position method to get the current left position of our scroll container.  This is’ myposition = $(“#elementid”).position();’  and to get the left specifically you can now use ‘myposition.left’.  Getting the top position can be used the same way.  Once we have this we can just check our current position in relation to our starting position and the overall width of our scroll container.  Depending upon the numbers returned we can either show or hide our left and right buttons using the jQuery show/hide methods.  I would suggest trying this with Firebug in Mozilla.  You will be able to watch the CSS position changing as you scroll.  Write your current x position and the overall width to the console and you can really see how this is working.

Lastly we just need to move it when we click the left and right buttons.  This is the easiest part of the whole process believe it or not.  When our button is clicked we need to use jQuery’s animate() method.  So for us we will pass in the thing we want to scroll (the scroll container).animate().  Inside the animate method I’m passing how I want it to animate, how long I want the animation to be, and a callback function.  Simply put we want to animate the CSS left position up or down the width our our mask (750 pixels).  Write this as ‘left: “+=750px”‘ inside of curly brackets.  The ‘+=’ adds to the width.  ‘-=’ subtracts from the width. So that is the gist of creating a slider like we often see with SPRY.  More often than not SPRY will probably be the easier way to go, but it never hurts to understand how the code your using works.

Tags
CategoryJavascript

Leave a Reply

*
(Won't be published) *