Blog

Where we discuss our work, thoughts, and process

Tutorial: A Horizontal jQuery Accordion using Custom Event Binding

This is the second of two posts about a
site we recently launched for a non-profit called Striving for More. This is a great new organization that has started with the goal of improving overall care for young cancer patients. It was a fun and deserving project with a great design:

The first post was about how to build a customjQuery Slideshow on top of some popular jQuery plugins. It covered the required html, css and js needed and it also gave a look into the through process that went into it. This post will take the same approach, but instead look at the custom jQuery horizontal accordion that is on the homepage. Unlike the last project, this one will be build without the help of any plugins. It was created entirely from scratch using jQuery custom events.

What is it?

Essentially, this is a horizontal accordion that also changes the text below it on each transition. The one difference between this and a traditional accordion is that when a slide becomes active or inactive, it doesn't just shrink. Instead it slides behind the other slides. Click around on it above to see what I mean.

The HTML

The html for this project is really straightforward. There is a group of slides and a group of content:

The html is in two logical groups, the slide images/navigation and the slide content. These are paired by convention using programatic id attributes. Notice that each of the image slides and the content slides has an id with the [SLIDE NUMBER] in it. This makes the javascript much simpler.

Ideally the content would be grouped in with the images. This would have made for better markup, as the related items would be put together. This would have required a lot of css positioning trickery since the content wasn't supposed to move with the slide. For the sake of overall simplicity, some html complexity was added.

The last thing worth noting here is that the slide button text is actually a rendered image. That text can't be rotated reliably in all browsers is really sad. I am confident that this will be accomplished shortly with Canvas. If you're wondering which browsers are the offenders here, you'll probably be surprised. Text can be rotated reliably in EVERY major browser except for Firefox 2.0. It even works in IE. Alas.

The CSS

The CSS for this project is probably the simplest part. You'll only notice one little quirk:

It's all straighforward except for that bit at the bottom. I've hardcoded the number of slides. This is typically something I like to avoid, but there were a couple of reasons for it on this project:

I was assured that these slides would be unchanged for quite some time.

At least some CSS Positioning would be required so the page wouldn't look broken while the JS loaded. By being exact there would be no jarring readjustment at all.

It was easier.

These reasons made the decision obvious. As a quick aside and bonus, here is the css that could be used to rotate the text in CSS. Note that this depends on slightly different markup and it just won't work in Firefox 2.0. So remeber that until FFox2.0 disappears this is useless, though fascinating.

The jQuery

The jQuery for this little project was the most fun. It ended up being very compact due to the intial positioning of the slides using CSS and because I used custom events.

What are custom events? In short, they are functions that you can bind to jQuery selectors. This lets you associate actions with the objects that do them, rather than with what triggers them. As an example, you could bind the event 'toggle' to a lightbulb and then trigger it from any number of switches. So if you have multiple switches, they all don't need to keep track of the lightbulb's state. They can just call toggle and the bulb will handle it. (If you like this example, don't credit me. It's borrowed from a great article on jQuery Custom Events written by Rebecca Murphey).

This is certainly terse, so it is worth explaining. I'll start with the events we are binding to '.slide', open and close. To set the stage, remember that each slide is either open (navigation on the right), or closed (navigation on the left). I am keeping track of this by applying an 'open' or 'closed' class to each slide. This is a fairly standard technique.

Where things might get a bit tricky lie within how an accordion works. The visibile slide isn't the only slide that is open. The slides that come after it must be open as well (their navigation is on the right). So when the second slide is active, the first must be closed and the second and third must be open. This problem gets handled with a little big of recursion.

The Event Binding

Let's look at the close event, as it is the simpler of the two. When we close a slide, we first check that it is open. If it is closed, there is nothing to do. If it is open, we close it and then close the slide immediately to its left. This repeats until there isn't a slide to the left or it reaches a slide that has already been closed.

The open event is only a little more complicated. It works in the exact same way as the close event, except trickles to the right. It also updates which slide is active at each stop along the way.

Finally you can see how the 'show' event is bound to the slide contents. All this does is remove an open class from every slide content, and then add it back to the one that has been triggered.

As you can see, a lot of complexity has been encapsulated under these events. This makes it really easy to jump to a particular slide. All that needs to happen is to trigger the 'open' event on the desired slide and the 'show' event on the correct content. This is exactly what the '.slidebutton' code does.

Putting it all together

With all of the pieces in place you can see it in action below. Be sure to leave any questions or comments you have about this in our comments below.

However it doesn't seem to do anything? Am I doing something wrong? Sorry to be a pain!

02.05.2010

Joel Sutherland

Jason,

You will need to add the code I provided after all of the code from this post. Basically it runs after the slides have been set up.

02.08.2010

Eric C

hey I realize this is an old tut, but is there any way to make the slides scroll automatically? with maybe a 4 or 5 second delay ?

04.24.2010

Wayne

Hi Joel,

Nice accordian, is there a way to have the links on the left of the image?

Cheers

Wayne.

05.02.2010

aaron b

i agree with eric - do you know of a way that we could have the slides automatically scroll every few seconds?

trying to figure it out and can't quite get it.

thanks!

05.05.2010

Andrew S. Roberts

I used this on our new Office of Campus Visits homepage. Great work, thanks! http://visit.iupui.edu/
07.07.2010

Hawaii Web Design

Effective slideshow and simple to use. I look forward to more tutorials in the future. Thanks!
09.29.2010

ale_mar

Hi guys!, How ya doing?
Let me ask... is there a way to apply an autoplay to this slideshow? Active triggers still running, too...
Thanks in advance! ;-)
11.11.2010

Joel Sutherland

ale_mar

Making this autoplay would just require more javascript. That said, it might make more sense to use something designed for that from the beginning. I like jQuery Cycle: http://jquery.malsup.com/cycle/
11.11.2010

ale_mar

Hi Joel! Thanks for your reply.
I was thinking about jQuery Cycle, too... which is very useful. But how can I use it in your accordion?
Is it enough what follows?
jQuery(document).ready(function($) {
$("#slideshow").css("overflow", "hidden");
$("#slides").cycle({
fx: 'fade',
speed:900,
timeout:3000,

});
});
/code>

I'll try and let you know. Thanks anyway, bye!11.12.2010

Dejan Prole

Hi,
Could someone please send me complete code, my email is dprole[at]gmail.com. I have some trouble with this accordion - nothing happens when I point mouse on links on right side.
Thank you,
Dejan
12.23.2010

jcwenzeldesign

Great stuff. Really helped me out of a jam. Easy to use and modify for personal use.

I have one question: I have been trying to develop a lower navigation which will also control the "accordion". Any ideas on how to make a lower link control the slide show as well?
03.30.2011

VeronicaC

Awesome looking slider, exactly what I'm looking for. However I am using Squarespace and am having trouble incorporating it into my site. I have determined that everything other than the jQuery code is working. (The animations & selection of sections)

Any suggestions/help?
08.09.2011

CSS sites

Great example of jquery, I like it very well.
10.17.2011

rahul

hi,
Actully i want dynamic accordion which gives me "Domain name" as parent Div and on click of that realted
Customers should be displayed in child Div. if it is possible then pls give me the solution in ASP.NET MVC 4 .... or just tell me the logic..... thanks for help....
07.19.2012