Showcases are a great way to show your visitors your latest addition
to your portfolio or to present the latest product or article. Many
sites use this technique to cram information into an area so that your
visitors do not miss your message.
This tutorial will show you how to create such a showcase by utilising jQuery.
jQuery makes animation easy. This tutorial will guide you through the
setting up of your HTML, CSS and the associated jQuery code to create
the showcase.
The HTML
The viewport div is our window to the content that you wish to
display to the user. We’ll use CSS later to ensure the viewport only
displays the content you want. Inside the div, we will be enclosing two
further divs; one for the sections and another for the labels which will
pop up when the viewport scrolls into view. Both of these will be
inside another div: scrollable which will be the element we use to
scroll all the content within it into view. The sections div will
contain four further divs which will represent our sections and the
labels div will contain another four divs to represent our labels.
Lastly, we’ll create a row of simple buttons so we can elect to scroll a
certain section into view.
7 | < div id = "section1" class = "section" > |
11 | < div id = "section2" class = "section" > |
12 | < h1 >The Eiffel Tower</ h1 > |
15 | < div id = "section3" class = "section" > |
16 | < h1 >Empire State Building</ h1 > |
19 | < div id = "section4" class = "section" > |
20 | < h1 >The Great Wall of China</ h1 > |
28 | < p >Also known as Ayre's rock</ p > |
32 | < p >In the world's most romantic city</ p > |
36 | < p >Site of the last hour of King Kong's life</ p > |
40 | < p >This can be seen from space</ p > |
49 | < div id = "scroll1" class = "button" ></ div > |
50 | < div id = "scroll2" class = "button" ></ div > |
51 | < div id = "scroll3" class = "button" ></ div > |
52 | < div id = "scroll4" class = "button" ></ div > |
The CSS
We’ll start with the viewport itself. We want to set the dimensions
of the viewport, ensure that any content within it does not flow out and
we’ll add a thick 5px solid border.
The sections and labels divs are very similar. The width will be
determined by the number of sections you want to have multiplied by the
width of each section. In this example, our sections are 600px wide and
we will be using four of them so the width of the #content and #label
divs will be 2400px (4 x 600px). The width and height are all we need to
style the sections div.
The label div is slightly different since we require it to slide out
of view when we click on a button and it does not need to be 300px as
this would obscure the entire viewport when it came into view. We’ll set
this to 100px high. We also need to ensure that the label appears when
the page is first loaded, so we set the bottom property to 100px so that
it appears 100px above the bottom of the div in which it resides. We
also require setting the position to relative so we can use the bottom
property.
Both contents and labels are wrapped in another div identified as
scrollable which will be the element we use to move all the content
within it. This needs to be set to the dimensions of the content div as
this contains all that will be viewable in the viewport. We need to set
the position relative since we will be taking advantage of the left
property via jQuery to scroll the content into view.
We’ll look at the individual section divs now to style them for our
purposes. Each div classed as section needs to float left of each other
otherwise the content will flow out of the containing div and onto the
next row. We need these to be next to each other so that when we alter
the left position of the #scrollable, the relevant section will come
into view. Our sections will be 600px wide by 300px hight wide but we’ll
add some padding of 10px so everything isn’t flush to the sides of the
viewport. Our height and width will need to be reduced by 20px to cater
for this.
The individual label divs will be 600px wide and 100px high with a
10px padding. We also need to float these left so that they appear next
to each other and don’t stack on top of each other. We’ll also set the
background colour of the label to grey and the colour of the text
to white.
We’ll add some images to the background. I used some images from
wikimedia commons, scaled them down to 600px by 300px and set them as
background images.
3 | background-image : url ( '../image/uluru.jpg' ); |
8 | background-image : url ( '../image/eiffeltower.jpg' ); |
13 | background-image : url ( '../image/empirestate.jpg' ); |
18 | background-image : url ( '../image/greatwall.jpg' ); |
The last bit of styling we need to do is the menu section which will
allow us to scroll through to the various sections. You can do this in
any manner you want but for this example, we’ll just use some simple
divs wich will be 30px by 30px, have a background colour of grey and be
spaced 5px from each other by setting a margin of 5px. These buttons
will all be wrapped in another div which we don’t need to style but
contains all of our buttons.
So that is all the css done and now we’re ready to get our hands dirty with jQuery.
The jQuery
Queuing Events
We’ll start first by examining what it is our showcase “widget” will
do. When we click on one of our buttons, we want our label to drop down
out of view, the new section to come into view and then the label to pop
back up again. We’ll be scrolling the scrollable div so we only need to
be concerned with scrolling that – everything within it will be
dragged along.
So the order of events is:
- hide the label
- scroll the viewport
- show the label
There are a number of ways to implement this but we’ll cover the
queue function that jQuery supplies. Queuing is the principle of adding
events to an object and then dequeuing them or executing them. We’ll
create a function which queues three functions to hide the label, scroll
the viewport and then show the label. Queuing an event requires
attaching the event to an object in the DOM. You can create custom
queues or, if not specified, you can use the default queue (called
‘fx’). Once you queue an event in fx, the first function will execute.
However, the next function needs to be explicitly called to execute.
The main function navigate will set up the queued events. We will
also add a function to clear the queue so that events don’t back up
which would result in the queue getting larger and taking longer to
complete. clearQueue(), if supplied with no arguments, will clear the
events on the default fx queue.
1 | function navigate(position) |
3 | $( '#scrollable' ).clearQueue(); |
5 | $( '#scrollable' ).queue(hideLabel); |
6 | $( '#scrollable' ).queue(scroll(position)); |
7 | $( '#scrollable' ).queue(showLabel); |
Animating the Elements
We’ll define these functions next by using the animate() method and make use of a callback to dequeue the next event.
To hide the label, we need to move the bottom position of the label
to 0px making it disappear from the viewport and we’ll nominate that
this takes a quarter of a second or 250 milliseconds. We also need to
ensure that the next event in the queue executes and so we create an
inline function dequeueing the next event.
9 | $( '#scrollable' ).dequeue(); |
Next, we need to scroll the scrollable div to the relevant position.
Since each section is 600px we need to move the div to the left 600px
for every section. To show the first section in the viewport, the left
property needs to be 0px which is the default state when the page is
loaded, to view the second section, we need to set left to –600px, the
third; –1200px and so on. This transition will take 500 milliseconds or
half a second. We also need to dequeue the next event in the queue so
again we create an anonymous function to do this:
1 | function scroll(position) |
3 | position = position + "px" ; |
5 | $( '#scrollable' ).animate( |
11 | $( '#scrollable' ).dequeue(); |
The last function needs to show the label again, so we set the bottom
css property back to 100px and ensure this takes place over
250 milliseconds. We don’t need to trigger the next event in the queue
as this is the last in the sequence.
Binding the Events
The next thing we need to do is attach the navigate event to relevant
elements on the page. In our case this would be the four buttons we
defined earlier. The best way to attach these events is to do it through
jQuery. The document needs to be fully loaded before we do this so we
use the ready() function to wrap the code in.
We use jQuery’s click function to instantiate an anonymous function
which in turn triggers the navigate function with an appropriate value
for position.
1 | $(document).ready( function () |
4 | $( '#scroll1' ).click( function () |
10 | $( '#scroll2' ).click( function () |
16 | $( '#scroll3' ).click( function () |
22 | $( '#scroll4' ).click( function () |
So that is all that is required to create the scrolling showcase
“widget” but we’ll just add a few more lines of jQuery to add some
opacity to the label and make it fade in when the mouse is over it and
fade out when the mouse is moved out of it. This code can simply be
added to the ready() function ensuring it isn’t executed until the
document is fully loaded. We’ll bind the event since, as you will see
later, we will need to unbind it in certain circumstances. The two
functions to fade in and fade out are defined as:
3 | $( '#label' ).stop().fadeTo(250,0.7); |
8 | $( '#label' ).stop().fadeTo(250,1); |
We’ll also add a piece of code to set the opacity initially to 0.7.
This is where jQuery really excels. There are many inconsistencies
between browsers with the css opacity property but we don’t have to
worry about that. All we need to do is specify the W3C standard opacity
property. jQuery does the rest. Again, this can be added to the ready()
function.
1 | $( '#label' ).css( "opacity" , "0.7" ); |
Tidying Up
You’ll notice that when using the button to select your new section,
if you move your mouse to the label quickly, the animation stops
suddenly. This is because we have bound an event to the label element
and used stop() to stop the events from queuing up and making the UI
unusable. We can detach this event and reattach it once the scrolling
has been completed so as not to cause disruption. In our navigate
function, we will unbind the event before creating the queue:
1 | function navigate(position) |
3 | $( '.label' ).unbind( 'mouseover' , fadeIn); |
4 | $( '.label' ).unbind( 'mouseout' , fadeOut); |
6 | $( '#scrollable' ).clearQueue(); |
8 | $( '#scrollable' ).queue(hideLabel); |
9 | $( '#scrollable' ).queue(scroll(position)); |
10 | $( '#scrollable' ).queue(showLabel); |
Now that the event is detached, the animation won’t be stopped should
our mouse enter the label area. We’ll need to reattach this once all
the animation is complete. A sensible place to do this would be to call
an anonymous callback function in the showLabel() function since this is
the last in the queue and will only execute when this is complete.
8 | $( '.label' ).bind( 'mouseover' , fadeIn); |
9 | $( '.label' ).bind( 'mouseout' , fadeOut); |
One final thing we should do is to ensure that no animation is called
if we are attempting to select a section that we are already on. We can
do this by string a variable which indicates which page we’re on and
then testing this in the navigate() function to determine whether we
should execute the transition. We’ll create a variable which is outside
the scope of any function so anywhere can have access to it called
currentPage and set this to 1 to begin with. We’ll alter the navigate()
function to take a second argument; page which will notify the function
which section is being called. This value can be tested against
currentPage to see if the animation should occur. If the current page is
not being called, we can animate and then set currentPage to be the
page that was called. The navigate() function should be updated to this
(note that we have declared the currentPage variable just above this):
3 | function navigate(position, page) |
5 | if (page != currentPage) |
9 | $( '.label' ).unbind( 'mouseover' , fadeIn); |
10 | $( '.label' ).unbind( 'mouseout' , fadeOut); |
12 | $( '#scrollable' ).clearQueue(); |
14 | $( '#scrollable' ).queue(hideLabel); |
15 | $( '#scrollable' ).queue(scroll(position)); |
16 | $( '#scrollable' ).queue(showLabel); |
The bindings to the buttons also need to be changed so that the page values are sent to navigate():
1 | $(document).ready( function () |
4 | $( '#scroll1' ).click( function () |
10 | $( '#scroll2' ).click( function () |
16 | $( '#scroll3' ).click( function () |
22 | $( '#scroll4' ).click( function () |
28 | $( '.label' ).bind( 'mouseover' , fadeIn); |
29 | $( '.label' ).bind( 'mouseout' , fadeOut); |
31 | $( '#label' ).css( "opacity" , "0.7" ); |
Summary
In this tutorial you learnt how to create a simple showcase widget.
You used HTML and CSS to style it and most importantly used the overflow
property to limit the view of the viewport. Queuing and dequeuing
events with jQuery enables you to execute events asynchronously and
binding and unbinding events enables you to exert more control over the
UI to prevent unnecessary animation. This example is easily extend to
create more sections. You just need to make sure the widths of #content,
#scrollable and #label divs are expanded to including the extra
sections that you wish (remember — 600px per section) and of course, add
an extra section in the #content div and a related label in the
#labels div.
No comments: