Creating a Horizontal Accordion - J Query

Problem
The jQuery UI library supports vertical accordions out of the box, and in fact there area few simple code snippets that can be used to create a rudimentary accordion effect.However, making the accordion run horizontally requires specific CSS and a slightly different take on the jQuery code.For this solution we won’t be using the template, because the markup is different for the horizontal accordion.

Solution

HTML

CSS

jQuery

Discussion

The HTML and CSS lay the accordion out so that the elements within it are all floated to the left. If you used this on a web page, you would probably expect to have to add a clearing element directly after the accordion to allow the following content to flow properly.
By floating the elements to the left, our accordion is set up with the h3 > a as the title to the content panel.
If CSS and JavaScript are disabled, then the content flows correctly and is readable by,for instance, Google’s search engine.
If CSS is turned on but JavaScript isn’t, the default view is to see all the content panels.
Using jQuery, we initialize the display by hiding all the panels except the first, and wehook click handlers to the headers to slide the content in and out of view.
The horizontal accordion has been written as a jQuery plugin, in particular to show that we don’t need to hard-code any variables within the accordion effect. We only pass the duration speed variable in to the plugin, which determines the duration of the effect. We could easily upgrade this plugin to also take an easing or callback.
It’s important to note that throughout this code, all the click handling and navigation of the DOM happens around the <h3>element, not the <a>element. This still works,keeping the code relatively simple (instead of having to navigate up and down from the<a>element to get the parent <h3>then the adjacent <div>element), but more importantly,offers keyboard accessibility because the <a>elements can be tabbed on to and triggered via the keyboard. We don’t have to bind the click handler to the <a>element, because when the <a>element has the click event triggered (via clicking or the keyboard),
it bubbles up through the DOM and is caught by our click handler on the <h3>element.
The plugin first collects the necessary parts of the accordion: the header, which will be clickable; the first visible panel, and the width of the panels (note that this version of the plugin works only for equal sized panels):
var $accordionHeaders = $(this).find('h3'), this is the current accordion wrapper element, typically a <div>.
From the accordion wrapper, our code collects all the <h3>elements. Note that we will make use of next() and prev() to change our DOM collection from the <h3>to the next
nodes in the DOM tree, in particular the accordion content panels: $open = $accordionHeaders.next().filter(':first'),$open is a temporary variable that will point to the current visible panel. We can’t use .is(':visible') because we’re actually reducing the width and the panel still has a CSS property of display: block. So, we will keep track of the current panel through this $open variable:

Finally in the initialization, we capture the width of the open panel so that we can animate the width of the panels correctly.
Two tasks are left:

  • Initialize the view of panels, showing only the first panel

  • Bind the click handles to show and hide the panels

To initialize the view, we must hide all the panels except the first. We must also set the width to zero to allow for the animate function to increase the width, rather than making it pop out when it is shown.
To achieve this, we use an inverse filter from the $open variable, in particular :not(:first):

Once we have our selection of panels that are not the first, we change the CSS properties to initialize them.
Finally, we attach the click handler.
Remembering that the $accordion Headers variable contains the h3 elements, the first thing we do is say this: if the <h3>clicked is the same as the currently open panel, then don’t do anything.
Since the $open variable is the panel, we use .prev() to navigate to the previous <h3>element and test whether it matches the current context of the clicked element.
If the clicked element is not the current open panel, we animate the $open panel width to zero, and the current clicked panel to the captured width.
Notice the very last line of the click handler:

Because jQuery usually returns jQuery (except when getting a value) and we’re animating the panel that will now be open, we can capture this at the same time in the $open variable, thus overwriting it with the latest panel.


All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

J Query Topics