在多个选项卡集中定位一个选项卡集

时间:2019-04-11 10:40:56

标签: jquery css tabs

我有一些JQuery可以控制选项卡的打开和关闭。效果很好-直到我有多组标签。单击功能会影响所有选项卡集。我希望能够将功能隔离到与之交互的选项卡集。我如何有效地做到这一点?

每个标签都具有唯一的ID

data-tab =“ tab-{{blockID}} {{tabCounter}}”>

<ul class="tabs list fa-ul ml2 pl0 tf">
  <li class="lh-copy pv2 ba bl-0 bt-0 br-0 b--dotted b--black-30" data-tab="tab-21">
    <a class="link pointer blue hover-teal no-underline d tab-hover-fix tab-link" target="_blank">
      <span class="fa-li"><i class="fas fa-caret-down blue"></i></span>TAB ONE</a>
    <div id="tab-21" class="tab-content w-100-ns pt2 pb2 dn-ns dn">CONTENT GOES HERE</div>
  </li>
  <li class="lh-copy pv2 ba bl-0 bt-0 br-0 b--dotted b--black-30 active" data-tab="tab-22">
    <a class="link pointer blue hover-teal no-underline d tab-hover-fix tab-link" target="_blank">
      <span class="fa-li"><i class="fas fa-caret-down blue teal rm-90"></i></span>TAB TWO</a>
    <div id="tab-22" class="tab-content w-100-ns pt2 pb2 dn-ns db">
      CONTENT TWO GOES HERE
    </div>
  </li>
</ul>
$('ul.tabs li').click(function() {
  var tab_id = $(this).attr('data-tab');
  var icon = $(this).find('span i');

  //Remove on all list items
  $('ul.tabs li').removeClass('active');
  $('ul.tabs li span i').removeClass('teal rm-90');

  //Remove on all div items
  $('.tab-content').removeClass('db');
  $('.tab-content').addClass('dn');

  //Add on current list item
  $(icon).addClass('teal rm-90');
  $(this).addClass('active');

  //Add on current div item
  $('ul.tabs').find("#" + tab_id).removeClass('dn');
  $('div.tabs').find("#" + tab_id).removeClass('dn');
  $('ul.tabs').find("#" + tab_id).addClass('db');
  $('div.tabs').find("#" + tab_id).addClass('db');
})

1 个答案:

答案 0 :(得分:3)

问题在于您的代码主要是遍历整个文档以寻找匹配项。我建议您找到clicked元素的标签容器(ul.tabs),然后将所有后续操作限定在该容器中。例如,与其像在JS的第6行中那样在标签容器内搜索 all li元素并删除.active类,而不是:

$('ul.tabs li').removeClass('active');

...我们可以改而利用.parents()查找特定于 标签的容器,而仅在该容器中查找,就像这样:

var tabContainer = $(this).parents('ul.tabs').eq(0); // this is a little overly safe-- if you are confident that the ul.tabs will always be the immediate parent, you can just use .parent()
tabContainer.find('li').removeClass('active');

我使用此技术创建了一个代码段,并验证了该代码段与上面的代码无法正常工作,但当我们将搜索范围限定为clicked元素的选项卡容器时,它可以正常工作。我随意猜测了几种样式来说明这一点:

$('ul.tabs li').click(function() {
  // cache $this
  var $this = $(this);
  
  var tab_id = $this.attr('data-tab');
  var icon = $this.find('span i');
  
  // find the parent tab container
  var tabContainer = $this.parents('ul.tabs').eq(0);

  //Remove on all list items
  tabContainer.find('li').removeClass('active');
  tabContainer.find('li span i').removeClass('teal rm-90');

  //Remove on all div items
  tabContainer.find('.tab-content').removeClass('db');
  tabContainer.find('.tab-content').addClass('dn');

  //Add on current list item
  $(icon).addClass('teal rm-90');
  $(this).addClass('active');

  //Add on current div item
  tabContainer.find("#" + tab_id).removeClass('dn');
  $('div.tabs').find("#" + tab_id).removeClass('dn');
  tabContainer.find("#" + tab_id).addClass('db');
  $('div.tabs').find("#" + tab_id).addClass('db');
})
.active {
  background-color: pink;
}

.db {
  display: block;
}

.dn {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="tabs list fa-ul ml2 pl0 tf">
  <li class="lh-copy pv2 ba bl-0 bt-0 br-0 b--dotted b--black-30" data-tab="tab-21">
    <a class="link pointer blue hover-teal no-underline d tab-hover-fix tab-link" target="_blank">
      <span class="fa-li"><i class="fas fa-caret-down blue"></i></span>TAB ONE</a>
    <div id="tab-21" class="tab-content w-100-ns pt2 pb2 dn-ns dn">CONTENT GOES HERE</div>
  </li>
  <li class="lh-copy pv2 ba bl-0 bt-0 br-0 b--dotted b--black-30 active" data-tab="tab-22">
    <a class="link pointer blue hover-teal no-underline d tab-hover-fix tab-link" target="_blank">
      <span class="fa-li"><i class="fas fa-caret-down blue teal rm-90"></i></span>TAB TWO</a>
    <div id="tab-22" class="tab-content w-100-ns pt2 pb2 dn-ns db">
      CONTENT TWO GOES HERE
    </div>
  </li>
</ul>

<ul class="tabs list fa-ul ml2 pl0 tf">
  <li class="lh-copy pv2 ba bl-0 bt-0 br-0 b--dotted b--black-30" data-tab="tab-23">
    <a class="link pointer blue hover-teal no-underline d tab-hover-fix tab-link" target="_blank">
      <span class="fa-li"><i class="fas fa-caret-down blue"></i></span>TAB ALPHA</a>
    <div id="tab-23" class="tab-content w-100-ns pt2 pb2 dn-ns dn">CONTENT GOES HERE</div>
  </li>
  <li class="lh-copy pv2 ba bl-0 bt-0 br-0 b--dotted b--black-30 active" data-tab="tab-24">
    <a class="link pointer blue hover-teal no-underline d tab-hover-fix tab-link" target="_blank">
      <span class="fa-li"><i class="fas fa-caret-down blue teal rm-90"></i></span>TAB BETA</a>
    <div id="tab-24" class="tab-content w-100-ns pt2 pb2 dn-ns db">
      CONTENT TWO GOES HERE
    </div>
  </li>
</ul>

只要我们正在审核您的代码,还有其他几件事-

  1. 您没有利用链接来缩短操作,也没有在变量中缓存重复的选择-这会损害代码的性能。
  2. 至少就所发布的示例而言,$('div.tabs')从不匹配任何内容,因此可以省略。

通过这两项调整,我们可以缩短代码长度并提高其性能:

$('ul.tabs li').click(function() {
  var $this = $(this);
  var tab_id = $this.attr('data-tab');
  var icon = $this.find('span i');
  var tabContainer = $this.parents('ul.tabs').eq(0);

  //Remove on all list items
  tabContainer.find('li').removeClass('active');
  tabContainer.find('li span i').removeClass('teal rm-90');

  //Remove on all div items
  tabContainer.find('.tab-content')
    .removeClass('db')
    .addClass('dn');

  //Add on current list item
  icon.addClass('teal rm-90');
  $this.addClass('active');

  //Add on current div item
  tabContainer.find("#" + tab_id)
    .removeClass('dn')
    .addClass('db');

})
.active {
  background-color: pink;
}

.db {
  display: block;
}

.dn {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="tabs list fa-ul ml2 pl0 tf">
  <li class="lh-copy pv2 ba bl-0 bt-0 br-0 b--dotted b--black-30" data-tab="tab-21">
    <a class="link pointer blue hover-teal no-underline d tab-hover-fix tab-link" target="_blank">
      <span class="fa-li"><i class="fas fa-caret-down blue"></i></span>TAB ONE</a>
    <div id="tab-21" class="tab-content w-100-ns pt2 pb2 dn-ns dn">CONTENT GOES HERE</div>
  </li>
  <li class="lh-copy pv2 ba bl-0 bt-0 br-0 b--dotted b--black-30 active" data-tab="tab-22">
    <a class="link pointer blue hover-teal no-underline d tab-hover-fix tab-link" target="_blank">
      <span class="fa-li"><i class="fas fa-caret-down blue teal rm-90"></i></span>TAB TWO</a>
    <div id="tab-22" class="tab-content w-100-ns pt2 pb2 dn-ns db">
      CONTENT TWO GOES HERE
    </div>
  </li>
</ul>

<ul class="tabs list fa-ul ml2 pl0 tf">
  <li class="lh-copy pv2 ba bl-0 bt-0 br-0 b--dotted b--black-30" data-tab="tab-23">
    <a class="link pointer blue hover-teal no-underline d tab-hover-fix tab-link" target="_blank">
      <span class="fa-li"><i class="fas fa-caret-down blue"></i></span>TAB ALPHA</a>
    <div id="tab-23" class="tab-content w-100-ns pt2 pb2 dn-ns dn">CONTENT GOES HERE</div>
  </li>
  <li class="lh-copy pv2 ba bl-0 bt-0 br-0 b--dotted b--black-30 active" data-tab="tab-24">
    <a class="link pointer blue hover-teal no-underline d tab-hover-fix tab-link" target="_blank">
      <span class="fa-li"><i class="fas fa-caret-down blue teal rm-90"></i></span>TAB BETA</a>
    <div id="tab-24" class="tab-content w-100-ns pt2 pb2 dn-ns db">
      CONTENT TWO GOES HERE
    </div>
  </li>
</ul>

最后,如果您打算在任意给定页面上包含这些内容的 lot ,建议您使用.on中的事件委托来代替.click更多性能提升。

相关问题