Ориентация на один набор вкладок в нескольких наборах вкладок - PullRequest
3 голосов
/ 11 апреля 2019

У меня есть JQuery, который управляет открытием и закрытием вкладок. Это прекрасно работает - пока у меня есть несколько наборов вкладок. На функциональность клика влияют все наборы вкладок. Я хочу иметь возможность изолировать функциональность от набора вкладок, с которыми взаимодействует. Как мне сделать это эффективно?

С каждой вкладкой связан уникальный идентификатор

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 Ответ

3 голосов
/ 17 апреля 2019

Проблема в том, что ваш код в основном перебирает весь документ в поисках совпадений.Я бы порекомендовал найти контейнер вкладок (ul.tabs) для элемента, по которому щелкнули, а затем определить область действия всех последующих операций с этим контейнером.Например, вместо поиска всех li элементов внутри контейнера вкладок и удаления класса .active, как у вас в шестой строке вашего JS:

$('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');

, который я создалфрагмент, использующий эту технику, и проверил, что, хотя он и не работал должным образом с вашим кодом выше, когда мы ограничиваем наш поиск до контейнера вкладок элемента, по которому щелкнули, он работает правильно.Я позволил себе угадать несколько стилей, чтобы проиллюстрировать эту мысль:

$('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>

Наконец, если вы намереваетесь включить лот из них на любой данной странице, может быть целесообразно использовать событиеделегирование в .on вместо .click для повышения производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...