Jquery: How to traverse dom to slideToggle groups of tab elements

时间:2016-07-11 19:07:02

标签: jquery tabs

I have a groups of tab-links and tab content panes on the same page, each with a varying number of tabs.

<div class="tab-content-group1">
  <div class="tabs-group">
    <a class="tab1">Tab 1</a>
    <a class="tab2">Tab 2</a>
    <a class="tab3">Tab 3</a>
  </div>
  <div class="tab-pane-group">
    <div class="tab-pane1">Tab Content 1</div>
    <div class="tab-pane2">Tab Content 2</div>
    <div class="tab-pane3">Tab Content 3</div>
  </div>
</div>

<div class="tab-content-group2">
  <div class="tabs-group">
    <a class="tab4">Tab 4</a>
    <a class="tab5">Tab 5</a>
    <a class="tab6">Tab 6</a>
    <a class="tab7">Tab 7</a>
  </div>
  <div class="tab-pane-group">
    <div class="tab-pane4">Tab Content 4</div>
    <div class="tab-pane5">Tab Content 5</div>
    <div class="tab-pane6">Tab Content 6</div>
    <div class="tab-pane7">Tab Content 7</div>
  </div>
</div>

<div class="tab-content-group3">
  <div class="tabs-group">
    <a class="tab8">Tab 8</a>
  </div>
  <div class="tab-pane-group">
    <div class="tab-pane8">Tab Content 8</div>
  </div>
</div>

Where, in each tab group, the first tab link should slideToggle the first tab-content when clicked, the second tab link slideToggles the second content and the same for 3 and 4. This is repeated for the other tab groups.

To slideToggle the content panes when the tab is clicked, I have been using this:

  $(".tab1").click(function() {
    $("tab1").slideToggle("slow", function() {});
  });

  $(".tab2").click(function() {
    $("tab2").slideToggle("slow", function() {});
  });

   $(".tab3").click(function() {
    $("tab3").slideToggle("slow", function() {});
  });

...etc for each tab.

Question 1) Is there a more efficient way to write the code so each tab and pane doesn't need a class hard-coding everything anytime new tabs or new tab groups are added (eg. tab1, tab2, tab-pane1 etc) .

(I was thinking of something like "determine which tab is being clicked in a tab-content-group (1st, 2nd 3rd etc) then find the next tab-pane-group and slideToggle the corresdponding tab-pane that's in there (1st tab toggles first tab-pane, 2nd tab toggles second tab-pane etc) – but I have no idea how to achieve this with JQuery!)

Please note I can't change the HTML structure.

Question 2) What is the best way to get these slideToggles to behave as though part of a group that is aware of each other's toggle state to make sure any open tabs are closed when new tabs are opened.

Many thanks for any advice.

2 个答案:

答案 0 :(得分:0)

With your HTML structure you could use index of each a element to slideToggle div's in .tab-pane-group

$('.tab-pane-group div').hide();
$('.tabs-group a').click(function() {
  var i = $(this).index();
  $(this).parent().next().find('div:eq(' + i + ')').slideToggle().siblings().slideUp();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tab-content-group1">
  <div class="tabs-group">
    <a class="tab1">Tab 1</a>
    <a class="tab2">Tab 2</a>
    <a class="tab3">Tab 3</a>
  </div>
  <div class="tab-pane-group">
    <div class="tab-pane1">Tab Content 1</div>
    <div class="tab-pane2">Tab Content 2</div>
    <div class="tab-pane3">Tab Content 3</div>
  </div>
</div>

<div class="tab-content-group2">
  <div class="tabs-group">
    <a class="tab4">Tab 4</a>
    <a class="tab5">Tab 5</a>
    <a class="tab6">Tab 6</a>
    <a class="tab7">Tab 7</a>
  </div>
  <div class="tab-pane-group">
    <div class="tab-pane4">Tab Content 4</div>
    <div class="tab-pane5">Tab Content 5</div>
    <div class="tab-pane6">Tab Content 6</div>
    <div class="tab-pane7">Tab Content 7</div>
  </div>
</div>

<div class="tab-content-group3">
  <div class="tabs-group">
    <a class="tab8">Tab 8</a>
  </div>
  <div class="tab-pane-group">
    <div class="tab-pane8">Tab Content 8</div>
  </div>
</div>

If you also want to hide divs in other .tab-pane-group you can use this

$('.tab-pane-group div').hide();
$('.tabs-group a').click(function() {
  var i = $(this).index();
  $('.tab-pane-group div').slideUp();
  $(this).parent().next().find('div:eq(' + i + ')').slideToggle();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tab-content-group1">
  <div class="tabs-group">
    <a class="tab1">Tab 1</a>
    <a class="tab2">Tab 2</a>
    <a class="tab3">Tab 3</a>
  </div>
  <div class="tab-pane-group">
    <div class="tab-pane1">Tab Content 1</div>
    <div class="tab-pane2">Tab Content 2</div>
    <div class="tab-pane3">Tab Content 3</div>
  </div>
</div>

<div class="tab-content-group2">
  <div class="tabs-group">
    <a class="tab4">Tab 4</a>
    <a class="tab5">Tab 5</a>
    <a class="tab6">Tab 6</a>
    <a class="tab7">Tab 7</a>
  </div>
  <div class="tab-pane-group">
    <div class="tab-pane4">Tab Content 4</div>
    <div class="tab-pane5">Tab Content 5</div>
    <div class="tab-pane6">Tab Content 6</div>
    <div class="tab-pane7">Tab Content 7</div>
  </div>
</div>

<div class="tab-content-group3">
  <div class="tabs-group">
    <a class="tab8">Tab 8</a>
  </div>
  <div class="tab-pane-group">
    <div class="tab-pane8">Tab Content 8</div>
  </div>
</div>

答案 1 :(得分:0)

Question 1)

Yes, you can select all tabs by $('.tab1, .tab2, .tab3, ...') and use $(this):

$('.tab1, .tab2, .tab3, ...').click(function() {
    $(this).slideToggle("slow", function() {});
});

or select all elements, that starts with .tab: $('[class^=tab]')

Question 2)

Hide all tabs, and open just that which is clicked

var tabs = $('[class^=tab]');

tabs.click(function() {
    tabs.slideUp("slow", function() {});
    $(this).slideDown("slow", function() {});
});