HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptMinor

How do I shorten my JQuery tabs?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
tabsjqueryshortenhow

Problem

I'm trying to clean up my JQuery code for my tabs. I have 3 different styles. How do I make the following shorter?

$(document).ready(function () {
    $('.tabs-style1 li').click(function () {
        var tab_id = $(this).attr('data-tab');
        $('.tabs-style1 li').removeClass('current');
        $('.tab-content-style1').removeClass('current');
        $(this).addClass('current');
        $("#" + tab_id).addClass('current');
    })
})

$(document).ready(function () {
    $('.tabs-style2 li').click(function () {
        var tab_id = $(this).attr('data-tab');
        $('.tabs-style2 li').removeClass('current');
        $('.tab-content-style2').removeClass('current');
        $(this).addClass('current');
        $("#" + tab_id).addClass('current');
    })
})

$(document).ready(function () {
    $('.tabs-style3 li').click(function () {
        var tab_id = $(this).attr('data-tab');
        $('.tabs-style3 li').removeClass('current');
        $('.tab-content-style3').removeClass('current');
        $(this).addClass('current');
        $("#" + tab_id).addClass('current');
    })
})


Your help will be appreciated!
http://michellecantin.ca/test/features/tabs/

Solution

The visual style of your tabs is actually independent of their functionality. That is, they all behave as tabs, regardless of how they look.

So, while you could make your code more generic by making the selector strings on the fly ($(".tab-content-" + styleName) etc.), I'd recommend something different.

I'd start by separating the classes that describe style from the ones that describe function. Then I'd use the structure of the markup to figure out the rest; not everything needs a class name.

I.e. given this markup, which is slightly changed/simplified from yours


  
    Tab One
    Tab Two
    Tab Three
    Tab Four
  

  
    Lorem ipsum...
  

  
    Duis aute...
  

  
    Ut enim...
  

  
    Sed do eiusmod...
  


The code can be shortened to

$(".tabs").each(function () {
  var container = $(this);
  container.find(".tabs-list li").on("click", function () {
    var tab = $(this),
        target = tab.data("tab");
    tab.addClass("current")
      .siblings().removeClass("current");
    container.children("#" + target).addClass("current")
      .siblings("div").removeClass("current");
  });
});


for any and all "tab areas" on the page. It'll also work if you add new styles later, or remove any of ones you have. I.e. the visual style is decoupled from the behavior. Also, you only need to change the class name in one place to re-style an entire tab area.

CSS-wise, simply scope your rules to .style1, .style2 etc. and perhaps use the direct-descendant operator, while keeping the base styling common for all styles

.tabs-style1 .tabs-list { ... }
.tabs-style1 .tabs-list li { ... }
.tabs-style1 > div { /* tab content styling */ }


Here's a demo (it's ugly - just demonstrating the functionality)

Code Snippets

<div class="tabs tabs-style1">
  <ul class="tabs-list">
    <li class="current" data-tab="tab-1">Tab One</li>
    <li data-tab="tab-2">Tab Two</li>
    <li data-tab="tab-3">Tab Three</li>
    <li data-tab="tab-4">Tab Four</li>
  </ul>

  <div id="tab-1" class="current">
    <p>Lorem ipsum...</p>
  </div>

  <div id="tab-2">
    <p>Duis aute...</p>
  </div>

  <div id="tab-3">
    <p>Ut enim...</p>
  </div>

  <div id="tab-4">
    <p>Sed do eiusmod...</p>
  </div>
</div>
$(".tabs").each(function () {
  var container = $(this);
  container.find(".tabs-list li").on("click", function () {
    var tab = $(this),
        target = tab.data("tab");
    tab.addClass("current")
      .siblings().removeClass("current");
    container.children("#" + target).addClass("current")
      .siblings("div").removeClass("current");
  });
});
.tabs-style1 .tabs-list { ... }
.tabs-style1 .tabs-list li { ... }
.tabs-style1 > div { /* tab content styling */ }

Context

StackExchange Code Review Q#33751, answer score: 4

Revisions (0)

No revisions yet.