{"authorId":1,"title":{"title":{}},"slug":"jquery-tabbed-navigation","postDate":1219107530,"expiryDate":null,"enabled":1,"fields":{"2":"<p>It seems like more and more these days, JavaScript tabbed interfaces are being used. There are plenty of scripts out there, but I think it is important to be able to do things yourself. A lot of JavaScript &ldquo;plugins&rdquo; that you will find online will give you way more than you really need, and you may understand how to use it, but you will not really understand what it is really doing.<\/p>\n\n<p>First, I thought I would walk through creating a tabbed navigation script with jQuery, and then modifying it so that it works without JavaScript.<\/p>\n<!--more-->\n<p>If you want to skip ahead, <a href=\"http:\/\/trevordavis.net\/play\/javascript-tabbed-navigation\/\">take a look at the sample jQuery tabbed interface<\/a>.<\/p>\n\n<h2>The Markup<\/h2>\n<p>I&rsquo;m going to set this up using classes so that it is possible to use this multiple times on a page. There are two different pieces to the markup: the navigation and the actual content for the tabs.<\/p>\n\n<h3>The Navigation<\/h3>\n<div class=\"codeblock\"><code>\n&lt;ul&nbsp;class=\"tabNav\"&gt;<br \/>&nbsp;&lt;li&nbsp;class=\"current\"&gt;&lt;a&nbsp;href=\"#\"&gt;Tab&nbsp;1&lt;\/a&gt;&lt;\/li&gt;<br \/>&nbsp;&lt;li&gt;&lt;a&nbsp;href=\"#\"&gt;Tab&nbsp;2&lt;\/a&gt;&lt;\/li&gt;<br \/>&nbsp;&lt;li&gt;&lt;a&nbsp;href=\"#\"&gt;Tab&nbsp;3&lt;\/a&gt;&lt;\/li&gt;<br \/>&nbsp;&lt;li&gt;&lt;a&nbsp;href=\"#\"&gt;Tab&nbsp;4&lt;\/a&gt;&lt;\/li&gt;<br \/>&nbsp;&lt;li&gt;&lt;a&nbsp;href=\"#\"&gt;Tab&nbsp;5&lt;\/a&gt;&lt;\/li&gt;<br \/>&lt;\/ul&gt;&nbsp;\n\n<\/code><\/div>\n<p>Pretty straightforward, just an un-ordered list. The JavaScript will accommodate any number of tabs. Notice that the first tab has a class of <strong>current<\/strong>. This will be the class to style to show the active tab.<\/p>\n\n<h3>The Tab Content<\/h3>\n<div class=\"codeblock\"><code>\n&lt;div&nbsp;class=\"tabContainer\"&gt;<br \/>&nbsp;&lt;div&nbsp;class=\"tab&nbsp;current\"&gt;<br \/>&nbsp;&nbsp;&amp;hellip;Content&nbsp;for&nbsp;Tab&nbsp;1&amp;hellip;<br \/>&nbsp;&lt;\/div&gt;<br \/>&nbsp;&lt;div&nbsp;class=\"tab\"&gt;<br \/>&nbsp;&nbsp;&amp;hellip;Content&nbsp;for&nbsp;Tab&nbsp;2&amp;hellip;<br \/>&nbsp;&lt;\/div&gt;<br \/>&nbsp;&lt;div&nbsp;class=\"tab\"&gt;<br \/>&nbsp;&nbsp;&amp;hellip;Content&nbsp;for&nbsp;Tab&nbsp;3&amp;hellip;<br \/>&nbsp;&lt;\/div&gt;<br \/>&nbsp;&lt;div&nbsp;class=\"tab\"&gt;<br \/>&nbsp;&nbsp;&amp;hellip;Content&nbsp;for&nbsp;Tab&nbsp;4&amp;hellip;<br \/>&nbsp;&lt;\/div&gt;<br \/>&nbsp;&lt;div&nbsp;class=\"tab\"&gt;<br \/>&nbsp;&nbsp;&amp;hellip;Content&nbsp;for&nbsp;Tab&nbsp;5&amp;hellip;<br \/>&nbsp;&lt;\/div&gt;<br \/>&lt;\/div&gt;&nbsp;\n\n<\/code><\/div>\n<p>Again, pretty straightforward: a container and a div for each of the tabs&rsquo; content. A couple of things to note: the first tab content also has a class of <strong>current<\/strong>, and the tabs&rsquo; content divs need to appear in the same order as the navigation.<\/p>\n\n<h2>Some Basic CSS<\/h2>\n<p>I&rsquo;m not going to explain how I completely style my example, but I will highlight the necessary styles for the tabs to work.<\/p>\n\n<p>To highlight the active tab, this is what you want to style:<\/p>\n<div class=\"codeblock\"><code>\nul.tabNav&nbsp;li.current&nbsp;a&nbsp;&#123;&nbsp;&amp;hellip;&nbsp;&#125;&nbsp;\n\n<\/code><\/div>\n\n<p>In order to hide all of the tabs&rsquo; contents except for the active tab, these are the styles that are necessary:<\/p>\n<div class=\"codeblock\"><code>\ndiv.tabContainer&nbsp;div.tab&nbsp;&#123;&nbsp;display:&nbsp;none;&nbsp;&#125;<br \/>div.tabContainer&nbsp;div.current&nbsp;&#123;&nbsp;display:&nbsp;block;&nbsp;&#125;&nbsp;\n\n<\/code><\/div>\n\n<h2>The JavaScript<\/h2>\n<p>Ok, this is definitely the meat of the post. Since I wanted this to be as generic and simple as possible, I made heavy use of the <a href=\"http:\/\/docs.jquery.com\/Traversing\/parent\">parent<\/a> and <a href=\"http:\/\/docs.jquery.com\/Traversing\/children\">children<\/a> selectors.<\/p>\n\n<p>So to start, we want to <strong>add onclick events to the tabs<\/strong>:<\/p>\n<div class=\"codeblock\"><code>\n$(document).ready(function()&#123;<br \/>&nbsp;$('ul.tabNav&nbsp;a').click(function()&nbsp;&#123;<br \/>&nbsp;&nbsp;&amp;hellip;<br \/>&nbsp;&nbsp;return&nbsp;false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br \/>&nbsp;&#125;);<br \/>&#125;);&nbsp;\n\n<\/code><\/div>\n\n<p>When each tab is clicked, we want to see which tab was clicked on so that we can show the appropriate content. So we count the previous number of siblings of the parent (the list item) and store it in the <strong>curChildIndex<\/strong> variable:<\/p>\n<div class=\"codeblock\"><code>\n$(document).ready(function()&#123;<br \/>&nbsp;$('ul.tabNav&nbsp;a').click(function()&nbsp;&#123;<br \/>&nbsp;&nbsp;&lt;strong&gt;var&nbsp;curChildIndex&nbsp;=&nbsp;$(this).parent().prevAll().length&nbsp;+&nbsp;1;&lt;\/strong&gt;<br \/>&nbsp;&nbsp;&amp;hellip;<br \/>&nbsp;&nbsp;return&nbsp;false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br \/>&nbsp;&#125;);<br \/>&#125;);&nbsp;\n\n<\/code><\/div>\n\n<p>Next, we want to remove the class of current from the currently selected tab, and add the class of current to the tab we just clicked:<\/p>\n<div class=\"codeblock\"><code>\n$(document).ready(function()&#123;<br \/>&nbsp;$('ul.tabNav&nbsp;a').click(function()&nbsp;&#123;<br \/>&nbsp;&nbsp;var&nbsp;curChildIndex&nbsp;=&nbsp;$(this).parent().prevAll().length&nbsp;+&nbsp;1;<br \/>&nbsp;&nbsp;&lt;strong&gt;$(this).parent().parent().children('.current').removeClass('current');<br \/>&nbsp;&nbsp;$(this).parent().addClass('current');&lt;\/strong&gt;<br \/>&nbsp;&nbsp;&amp;hellip;<br \/>&nbsp;&nbsp;return&nbsp;false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br \/>&nbsp;&#125;);<br \/>&#125;);&nbsp;\n\n<\/code><\/div>\n\n<p>The final step is to hide the tab content that is currently showing and to show the tab content that matches the tab that was just clicked on. This is where we will make use of the <strong>curChildIndex<\/strong> variable and the <a href=\"http:\/\/docs.jquery.com\/Selectors\/nthChild\">nth Child Selector<\/a>:<\/p>\n\n<div class=\"codeblock\"><code>\n$(document).ready(function()&#123;<br \/>&nbsp;$('ul.tabNav&nbsp;a').click(function()&nbsp;&#123;<br \/>&nbsp;&nbsp;var&nbsp;curChildIndex&nbsp;=&nbsp;$(this).parent().prevAll().length&nbsp;+&nbsp;1;<br \/>&nbsp;&nbsp;$(this).parent().parent().children('.current').removeClass('current');<br \/>&nbsp;&nbsp;$(this).parent().addClass('current');<br \/>&nbsp;&nbsp;&lt;strong&gt;$(this).parent().parent().next('.tabContainer').children('.current').slideUp('fast',function()&nbsp;&#123;<br \/>&nbsp;&nbsp;&nbsp;$(this).removeClass('current');<br \/>&nbsp;&nbsp;&nbsp;$(this).parent().children('div:nth-child('+curChildIndex+')').slideDown('normal',function()&nbsp;&#123;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;$(this).addClass('current');<br \/>&nbsp;&nbsp;&nbsp;&#125;);<br \/>&nbsp;&nbsp;&#125;);&lt;\/strong&gt;<br \/>&nbsp;&nbsp;return&nbsp;false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br \/>&nbsp;&#125;);<br \/>&#125;);&nbsp;\n\n<\/code><\/div>\n\n<p>The previous snippet of the code is traversing from the clicked tab ,<strong>(this)<\/strong>, to the current content that has a class of <strong>current<\/strong>, sliding that up, and removing the class of current. Once that is complete, we are selecting the tab content that matches the tab clicked, sliding it down, and adding the class of current.<\/p>\n\n<p><a href=\"http:\/\/trevordavis.net\/play\/javascript-tabbed-navigation\/\">Take a look at the sample jQuery tabbed interface<\/a> to see it in action.<\/p>\n\n<h2>Making it Work for Non-JavaScript Users<\/h2>\n<p>Now, that works great, but what about people who don&rsquo;t have JavaScript enabled? Sure it&rsquo;s a very small number, but we still want to account for those people.<\/p>\n<p>Most other JavaScript tab scripts use JavaScript to hide the non-active tab content sections or to write in the tabbed navigation, but then you get that flash of changing content. My idea is to use CSS to hide the non active tab content (which I discussed earlier) and pass a parameter into the URL to select which tab to show.<\/p>\n<h3>The Code<\/h3>\n<p>Below is the new code for the tab navigation:<\/p>\n<div class=\"codeblock\"><code>\n&lt;ul&nbsp;class=\"tabNav\"&gt;<br \/>&nbsp;&lt;li&lt;?php&nbsp;if(!isset($_GET&#91;'tab'&#93;))&nbsp;echo&nbsp;'&nbsp;class=\"current\"';?&gt;&gt;&lt;a&nbsp;href=\"\"&gt;Tab&nbsp;1&lt;\/a&gt;&lt;\/li&gt;<br \/>&nbsp;&lt;li&lt;?php&nbsp;if(isset($_GET&#91;'tab'&#93;)&nbsp;&amp;&amp;&nbsp;$_GET&#91;'tab'&#93;&nbsp;==&nbsp;2)&nbsp;echo&nbsp;'&nbsp;class=\"current\"';?&gt;&gt;&lt;a&nbsp;href=\"?tab=2\"&gt;Tab&nbsp;2&lt;\/a&gt;&lt;\/li&gt;<br \/>&nbsp;&lt;li&lt;?php&nbsp;if(isset($_GET&#91;'tab'&#93;)&nbsp;&amp;&amp;&nbsp;$_GET&#91;'tab'&#93;&nbsp;==&nbsp;3)&nbsp;echo&nbsp;'&nbsp;class=\"current\"';?&gt;&gt;&lt;a&nbsp;href=\"?tab=3\"&gt;Tab&nbsp;3&lt;\/a&gt;&lt;\/li&gt;<br \/>&nbsp;&lt;li&lt;?php&nbsp;if(isset($_GET&#91;'tab'&#93;)&nbsp;&amp;&amp;&nbsp;$_GET&#91;'tab'&#93;&nbsp;==&nbsp;4)&nbsp;echo&nbsp;'&nbsp;class=\"current\"';?&gt;&gt;&lt;a&nbsp;href=\"?tab=4\"&gt;Tab&nbsp;4&lt;\/a&gt;&lt;\/li&gt;<br \/>&nbsp;&lt;li&lt;?php&nbsp;if(isset($_GET&#91;'tab'&#93;)&nbsp;&amp;&amp;&nbsp;$_GET&#91;'tab'&#93;&nbsp;==&nbsp;5)&nbsp;echo&nbsp;'&nbsp;class=\"current\"';?&gt;&gt;&lt;a&nbsp;href=\"?tab=5\"&gt;Tab&nbsp;5&lt;\/a&gt;&lt;\/li&gt;<br \/>&lt;\/ul&gt;&nbsp;\n\n<\/code><\/div>\n\n<p>Basically, I am checking to see if the variable <strong>tab<\/strong> is set in the URL, and determining the value of it. I also use the same logic for the tab content. <a href=\"http:\/\/trevordavis.net\/play\/javascript-tabbed-navigation\/?tab=3\">This is the example page with tab 3 displaying<\/a>. So basically, if the user does not have JavaScript, it would reload the entire page and display the correct tab.<\/p>\n\n<h2>Conclusion<\/h2>\n<p>This was just a simple example of jQuery, and the possibilities are endless. Instead of being so quick to use a plugin or someone&rsquo;s code, try to do it yourself. You will become a much better programmer because of it. Even if you aren&rsquo;t doing things as efficiently as possible, you will learn something new every time.","4":{"website":{}}}}