We recently released a new version of the Mint.com homepage with a tabbing system that: allows linking to a specific tabs, restoring the last tab on a page refresh, and basic tab history management in the better browsers (FireFox and Safari)… along with managing the tabs themselves to display the appropriate content. I have taken that concept, rewriting it to be lightweight (only 8kb uncompressed), leverage YUI and be configurable, in case you do not use the same conventions that we use at Mint. The new widget is HashTab and we will be today
This widget uses a combination of naming convention and DOM queues to know which tab to display in a variety of situations. Lets discuss the simplest (default) case where you have a collection of tabs inside of a UL tag and a collection of tab content inside of a DIV tag. Your HTML will look something like this:
Example 1: Default HTML
<ul id="tab-example"> <li class="selected" id="tab-nav1"><a href="#nav1">tab 1</a></li> <li id="tab-nav2"><a href="#nav2">tab 2</a></li> <li id="tab-nav3"><a href="#nav3">tab 3</a></li> </ul> <div id="content-example"> <div class="selected" id="content-nav1">Content 1</div> <div id="content-nav2">Content 2</div> <div id="content-nav3">Content 3</div> </div>
First you should notice that all the IDs consist of two words separated by a dash. Each word is a key used by HashTab to identify elements and interact with the DOM. The tab UL container ID begins with the key "tab", which is also the first key of the IDs for each tab. The second word in the tab UL container ID is used to uniquely identify this tab container from any other on the page and wont be explicitly used by HashTab. The content container works in the same way, where the first key in the container ID is the same as the first key in the IDs of each of the content sections. The second word in each of the tabs and content sections should have a 1 to 1 ratio with each other, so if there is a tab with ID "tab-nav1", then there should be a content section with ID "content-nav1". That is how the HashTab knows that clicking on the first tab should show the first content section. Lastly, inside of each tab is an anchor, that should link to the same hash as the second key in the tab ID (so "tab-nav1" should have an anchor tag with a href of "#nav1").
In addition to responding to clicks, HashTab also understands that if the page is requested with one of the hashes that is recognizes, then it will display that tab when the page loads. For example, the url: "http://www.mattsnider.com/hashTabTest.html#tab4" will initialize the page with the 4th tab selected. HashTab is also smart enough to ignore hash values that are not part of the tab system, so you can still link to other anchors on your pages while using HashTab. In addition to linking to specific tabs, when the page refreshes HashTab will initialize the tabs to the last selected tab. And if you are using Safari or FireFox, HashTab will handle both forward and backwards history navigation (these browsers could be supported with only 6 lines of code).
Instantiating a new HashTab is easy, you need to only pass in the ID for the tab and content containers, plus an optional config Object as a third parameters:
Example 2: HashTab Instantiation
var hashTab = Core.Widget.HashTab(tab-example,content-example);
The configuration object allows you to customize almost any part of the widget. Below is an explanation of the keys recognized by HashTab:
Example 3: HashTab Configurationdelimiter: the character used to separate keys in the ID attribute for hashTab DOM nodes; default is
elementContent: the type of node used for each of the content nodes; default is
elementTab: the type of node used for each of the tab nodes; default is
interval: the poll time to check for history changes; default is 250 (1/4 second)
selected: the class to apply when a node is selected; default is
triggerEvent: the event to trigger tabbing; default is
Here is a Test Page showing how, in the first example, the default HashTab work, and how to use a few of the configuration settings in the second. Most importantly, notice how both HashTab widgets work independent of each other.