{"id":363,"date":"2009-01-25T15:06:17","date_gmt":"2009-01-25T20:06:17","guid":{"rendered":"http:\/\/cssnewbie.com\/?p=363"},"modified":"2009-01-25T15:06:17","modified_gmt":"2009-01-25T20:06:17","slug":"advanced-jquery-tabbed-box-techniques","status":"publish","type":"post","link":"https:\/\/cssdeck.com\/blog\/advanced-jquery-tabbed-box-techniques\/","title":{"rendered":"Advanced jQuery Tabbed Box Techniques"},"content":{"rendered":"<p><a href=\"http:\/\/cssnewbie.com\/example\/tabbed-box\/advanced.html\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/cssdeck.com\/blog\/wp-content\/uploads\/2009\/01\/tabbed-animated.gif\" alt=\"animated tabbed box interface\" title=\"animated tabbed box interface\" width=\"579\" height=\"200\" class=\"alignnone size-full wp-image-364\" \/><\/a><\/p>\n<p><a href=\"http:\/\/cssnewbie.com\/build-a-tabbed-box-with-css-and-jquery\/\">Last week\u2019s article<\/a> covered how to build a tabbed box interface, starting with Photoshop, and moving through XHTML and CSS to our basic jQuery functionality. If you missed it, I would highly recommend starting your reading there. This article will show you how to use jQuery to make your tabbed interface more attractive and interactive. Specifically, I\u2019ll show you how to:<\/p>\n<ul>\n<li>Make your tabs all the same height<\/li>\n<li>Automatically rotate through your tabbed content<\/li>\n<li>Stop the rotation when the user is interacting with the content<\/li>\n<\/ul>\n<h3>Equal Height Tabs<\/h3>\n<p>The tabbed interface we built last week was fully functional, but one nicety I\u2019d like to add is the option to have all your tabs be the same height \u2013 a height that is determined by the content within the tabs, not any number I arbitrarily determine in advance.<!--more--><\/p>\n<p>While there are several ways to calculate and apply height in jQuery, the fastest and easiest means to our end would be to use <a href=\"http:\/\/cssnewbie.com\/equalheights-jquery-plugin\/\">the equalHeights jQuery plugin I developed and wrote about recently.<\/a> By using that plugin, we\u2019d only have to make a single addition to the \u201cdocument ready\u201d portion of our jQuery:<\/p>\n<pre lang=\"javascript\" escaped=\"true\" line=\"1\">$(\".tabbed-content\").equalHeights();<\/pre>\n<p>This will cycle through all of our tabbed content divs and equalize their heights based on the height of the tallest div. The benefit of this is the content around our tabbed box won\u2019t shift up or down each time the user switches tabs, resulting in a more pleasant visual experience.<\/p>\n<h3>Rotate Through Tabbed Content<\/h3>\n<p>While tabbed boxes like the one we\u2019ve built are a great way to fit a large amount of content in a small space, they do have one drawback: many users never click through the tabs to see what all is offered, meaning they only ever see the content on the first tab. My proposed solution to this problem is to automatically rotate through the tabs.<\/p>\n<p>This solution has two benefits: first, the movement is more likely to catch the users\u2019 eyes, increasing the chances they\u2019ll notice the tabbed box in the first place. Second, it allows your users to see all the content your box contains instead of just the first tab.<\/p>\n<p>Making this adjustment to our jQuery requires edits in several areas, so I\u2019ll show you the new code in its entirety before explaining what it all does:<\/p>\n<pre lang=\"javascript\" escaped=\"true\" line=\"1\">var currentTab = 0; \nvar rotateSpeed = 5000;\nvar numTabs;.\nvar autoRotate;\n\nfunction openTab(clickedTab) {\n\tvar thisTab = $(&quot;.tabbed-box .tabs a&quot;).index(clickedTab);\n\t$(&quot;.tabbed-box .tabs li a&quot;).removeClass(&quot;active&quot;);\n\t$(&quot;.tabbed-box .tabs li a:eq(&quot;+thisTab+&quot;)&quot;).addClass(&quot;active&quot;);\n\t$(&quot;.tabbed-box .tabbed-content&quot;).hide();\n\t$(&quot;.tabbed-box .tabbed-content:eq(&quot;+thisTab+&quot;)&quot;).show();\n\tcurrentTab = thisTab;\n}\n\nfunction rotateTabs() {\n\tvar nextTab = (currentTab == (numTabs - 1)) ? 0 : currentTab + 1;\n\topenTab($(&quot;.tabbed-box .tabs li a:eq(&quot;+nextTab+&quot;)&quot;));\n}\n\n$(document).ready(function() {\n\t$(&quot;.tabbed-content&quot;).equalHeights();\n\tnumTabs = $(&quot;.tabbed-box .tabs li a&quot;).length;\n\t\n\t$(&quot;.tabbed-box .tabs li a&quot;).click(function() { \n\t\topenTab($(this)); return false; \n\t});\n\t\n\tautoRotate = setInterval(&quot;rotateTabs()&quot;, rotateSpeed);\t\n\t$(&quot;.tabbed-box .tabs li a:eq(&quot;+currentTab+&quot;)&quot;).click()\t\n});<\/pre>\n<p>The first variable, currentTab, is unchanged from our first iteration. But then we\u2019ve added three new variables:<\/p>\n<ul>\n<li>rotateSpeed is the number of milliseconds to wait before switching tabs.<\/li>\n<li>numTabs is a variable that will contain the total number of tabs in our box. We\u2019re initializing it at the beginning so we can use it in all our functions.<\/li>\n<li>autoRotate is a variable we\u2019ll use later.<\/li>\n<\/ul>\n<p>Our openTab function hasn\u2019t changed. If you\u2019d like to understand how it works, <a href=\"http:\/\/cssnewbie.com\/build-a-tabbed-box-with-css-and-jquery\/\">please refer to the first article.<\/a><\/p>\n<p>Next we\u2019ve written a new function called rotateTabs. This function will handle the math required to determine which tab should be opened next. First we set a new variable, nextTab. What we set nextTab to depends on which tab we\u2019re on currently. The function looks at currentTab: if currentTab is our last tab in the list, it starts back over at the beginning (the tab with an index of 0). Otherwise, nextTab is simply the next tab in the list. Once we\u2019ve determined our next tab, we call the openTab function, which prevents us from having to duplicate all that heavy lifting.<\/p>\n<p>We\u2019ve added two lines to our document ready function.  The first sets the numTabs variable to be the number of tabs in our box. We don\u2019t populate this variable until the document is ready, because otherwise it will try to count the tabs before our tabs have loaded and will return a length of -1 (aka, none found). <\/p>\n<p>The second bit we added is towards the end, where we set autoRotate. In autoRotate we\u2019re calling the JavasScript setInterval function, which executes a piece of JavaScript on a regular interval. As we\u2019ve written it, we will be calling our autoRotate function every \u201crotateSpeed\u201d milliseconds. This means that when our document loads, it will wait that many milliseconds, then switch to the next tab, then pause again, then switch again infinitely. <\/p>\n<p>Pretty neat, huh? <a href=\"http:\/\/cssnewbie.com\/example\/tabbed-box\/rotate.html\">You can see this functionality in action here.<\/a><\/p>\n<h3>Stopping the Rotation<\/h3>\n<p>Now, automatically rotating your tabs is a pretty awesome effect, but at some point you\u2019re probably going to want that rotation to stop. Specifically, you don\u2019t want your tabs switching when your users are interacting with them. <\/p>\n<p>I tested several scenarios on when and how to stop the tabs from rotating before deciding on how I\u2019m doing it here. It only requires editing a couple of lines from our document ready function:<\/p>\n<pre lang=\"javascript\" escaped=\"true\" line=\"1\">$(document).ready(function() {\n\t$(&quot;.tabbed-content&quot;).equalHeights();\n\tnumTabs = $(&quot;.tabbed-box .tabs li a&quot;).length;\n\t$(&quot;.tabbed-box .tabs li a&quot;).click(function() { \n\t\topenTab($(this)); return false; \n\t});\n\t$(&quot;.tabbed-box&quot;).mouseover(function(){clearInterval(autoRotate)})\n\t.mouseout(function(){autoRotate = setInterval(&quot;rotateTabs()&quot;, rotateSpeed)});\n\t\n\t$(&quot;.tabbed-box .tabs li a:eq(&quot;+currentTab+&quot;)&quot;).click()\n\t$(&quot;.tabbed-box&quot;).mouseout();\n\t\n});<\/pre>\n<p>Here we\u2019ve replaced our setInterval function with something a little more complex. We\u2019re now using both setInterval and clearInterval (which stops setInterval), and we\u2019re applying them when the user\u2019s mouse interacts with our tabbed box. <\/p>\n<p>Specifically, we\u2019re letting the box auto-rotate whenever the mouse is nowhere near the box, and stopping the box from rotating whenever the mouse is over the box. This means that as long as the user has the mouse over the box, as if they were reading, or clicking through the tabs, or clicking on something inside one of our tabs, the tabs wouldn\u2019t switch on them. But as soon as they\u2019re done interacting with the box, it\u2019ll switch back to its regular rotation.<\/p>\n<p>This does require one extra line at the end of the script, to force a \u201cmouseout\u201d event on the tabbed box, which gets things rotating by default.<\/p>\n<p><a href=\"http:\/\/cssnewbie.com\/example\/tabbed-box\/advanced.html\">You can see our fully functional tabbed interface here.<\/a> Give it a try: watch it rotate through, and then try interacting with the box a bit. You\u2019ll see that the tabs don\u2019t automatically move, as long as you\u2019re actively engaged with the box.<\/p>\n<p>And that\u2019s that! I hope you\u2019ve found this mini-series helpful, and I\u2019d love to see how you\u2019ve implemented this idea on your own websites. Drop me a line in the comments below if you do.<\/p>\n<div class=\"wp-socializer wpsr-share-icons \" data-lg-action=\"show\" data-sm-action=\"show\" data-sm-width=\"768\" ><h3>Share and Enjoy !<\/h3><div class=\"wpsr-si-inner\"><div class=\"wpsr-counter wpsrc-sz-32px\" style=\"color:#000\"><span class=\"scount\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook,twitter,linkedin,pinterest,print,pdf\">0<\/span><\/span><small class=\"stext\">Shares<\/small><\/div><div class=\"socializer sr-popup sr-32px sr-circle sr-opacity sr-pad sr-count-1 sr-count-1\"><span class=\"sr-facebook\"><a rel=\"nofollow\" href=\"https:\/\/www.facebook.com\/share.php?u=\" target=\"_blank\"  title=\"Share this on Facebook\"  style=\"color: #ffffff\" ><i class=\"fab fa-facebook-f\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"facebook\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-twitter\"><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/intent\/tweet?text=%20-%20%20\" target=\"_blank\"  title=\"Tweet this !\"  style=\"color: #ffffff\" ><i class=\"fab fa-twitter\"><\/i><\/a><\/span>\n<span class=\"sr-linkedin\"><a rel=\"nofollow\" href=\"https:\/\/www.linkedin.com\/sharing\/share-offsite\/?url=\" target=\"_blank\"  title=\"Add this to LinkedIn\"  style=\"color: #ffffff\" ><i class=\"fab fa-linkedin-in\"><\/i><\/a><\/span>\n<span class=\"sr-pinterest\"><a rel=\"nofollow\" href=\"https:\/\/www.pinterest.com\/pin\/create\/button\/?url=&amp;media=&amp;description=\" target=\"_blank\"  title=\"Submit this to Pinterest\"  style=\"color: #ffffff\" data-pin-custom=\"true\"><i class=\"fab fa-pinterest\"><\/i><span class=\"ctext\"><span data-wpsrs=\"\" data-wpsrs-svcs=\"pinterest\">0<\/span><\/span><\/a><\/span>\n<span class=\"sr-print\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Print this article \"  style=\"color: #ffffff\" ><i class=\"fa fa-print\"><\/i><\/a><\/span>\n<span class=\"sr-pdf\"><a rel=\"nofollow\" href=\"https:\/\/www.printfriendly.com\/print?url=\" target=\"_blank\"  title=\"Convert to PDF\"  style=\"color: #ffffff\" ><i class=\"fa fa-file-pdf\"><\/i><\/a><\/span><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>Last week&#8217;s article covered how to build a tabbed box interface, starting with Photoshop, and moving through XHTML and CSS to our basic jQuery functionality. If you missed it, I would highly recommend starting your reading there. This article will show you how to use jQuery to make your tabbed interface more attractive and interactive. [&#8230;]<\/p>\n<p><a class=\"more-link article\" href=\"https:\/\/cssdeck.com\/blog\/advanced-jquery-tabbed-box-techniques\/\" title=\"Click to read 'Advanced jQuery Tabbed Box Techniques'\">Read Article<\/a><\/p>\n","protected":false},"author":18,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[165,184,188],"tags":[62,79,290,55,291,88,358,372,374],"_links":{"self":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/363"}],"collection":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/comments?post=363"}],"version-history":[{"count":0,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/posts\/363\/revisions"}],"wp:attachment":[{"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/media?parent=363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/categories?post=363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cssdeck.com\/blog\/wp-json\/wp\/v2\/tags?post=363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}