Как мне сделать код JavaScript (jQuery) более компактным?

#javascript #jquery

#javascript #jquery

Вопрос:

У меня есть простой код ниже, который похож на вкладки.

Код:

 $(".tab-1").click(function(){
    $(".content div").removeClass("active")
    $(".content .content-1").addClass("active")
    $(".tabs span").removeClass("active-tab")
    $(this).addClass("active-tab")
})

$(".tab-2").click(function(){
    $(".content div").removeClass("active")
    $(".content .content-2").addClass("active")
    $(".tabs span").removeClass("active-tab")
    $(this).addClass("active-tab")
})

$(".tab-3").click(function(){
    $(".content div").removeClass("active")
    $(".content .content-3").addClass("active")
    $(".tabs span").removeClass("active-tab")
    $(this).addClass("active-tab")
})  
 .tabs span {
    margin: 20px;
    padding: 20px;
    background: black;
    color: white;
    font-weight: 600;
    cursor: pointer;
}

.tabs .active-tab {
    background: #ccc;
    color: black;
}

.content div {
    display: none;
}

.content .active {
    display: block;
}  
     <div class="tabs">
      <span class="tab-1 active-tab">Tab 1</span>
      <span class="tab-2">Tab 2</span>
      <span class="tab-3">Tab 3</span>
    </div>
    <div class="content">
      <div class="content-1 active">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 1.</p>
      </div>
      <div class="content-2">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 2.</p>
      </div>
      <div class="content-3">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 3.</p>
      </div>
    </div>
    <script
        src="https://code.jquery.com/jquery-3.4.1.min.js"
        integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
        crossorigin="anonymous">
    </script>  

Как вы можете видеть, это довольно просто. Вы нажимаете на разные вкладки, и на основе этого содержимое не меняет ничего слишком сложного, и оно работает. Проблема в том, что JS слишком повторяющийся, а также, если бы было 5-6-7 элементов, было бы больно, если бы я решил, что хочу что-то изменить, потому что мне пришлось бы просматривать каждый элемент по отдельности. Мой вопрос в том, как мне сделать код более компактным и как я могу добавить больше элементов без необходимости вносить изменения в JS?

Комментарии:

1. Лучший совет, который я могу дать, прекратите использовать jquery. Долгосрочное решение.

2. Обзор кода Обмен стеком

Ответ №1:

Вы можете опустить конкретные классы tab-1 и content-1 и использовать .index() :

 $(".tabs span").click(function(){
    $(".content div").removeClass("active")
                     .eq($(this).index()).addClass("active");
    $(".tabs span").removeClass("active-tab");
    $(this).addClass("active-tab");
})  
 .tabs span {
    margin: 20px;
    padding: 20px;
    background: black;
    color: white;
    font-weight: 600;
    cursor: pointer;
}

.tabs .active-tab {
    background: #ccc;
    color: black;
}

.content div {
    display: none;
}

.content .active {
    display: block;
}  
     <div class="tabs">
      <span class="active-tab">Tab 1</span>
      <span>Tab 2</span>
      <span>Tab 3</span>
    </div>
    <div class="content">
      <div class="active">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 1.</p>
      </div>
      <div>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 2.</p>
      </div>
      <div>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 3.</p>
      </div>
    </div>
    <script
        src="https://code.jquery.com/jquery-3.4.1.min.js"
        integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
        crossorigin="anonymous">
    </script>  

Ответ №2:

Методология, которую вы можете использовать для очистки этого кода, называется принципом «Не повторяйся» или DRY.

Чтобы достичь этого в этом случае, вы можете использовать this ключевое слово для ссылки на элемент, который вызвал click событие. Оттуда вы можете просмотреть DOM, чтобы найти связанные элементы, или использовать index() вкладку of, чтобы найти связанный контент, и изменить их, не выбирая их напрямую. Попробуйте это:

 let $tabs = $('.tabs > .tab');
let $content = $('.content-container > .content');

$(".tab").click(function() {
  $tabs.removeClass('active');
  let $tab = $(this).addClass('active');
  $content.removeClass('active').eq($tab.index()).addClass('active');
});  
 .tabs > .tab {
  margin: 20px;
  padding: 20px;
  background: black;
  color: white;
  font-weight: 600;
  cursor: pointer;
}

.tabs .active {
  background: #ccc;
  color: black;
}

.content-container .content {
  display: none;
}

.content-container .content.active {
  display: block;
}  
 <div class="tabs">
  <span class="tab active">Tab 1</span>
  <span class="tab">Tab 2</span>
  <span class="tab">Tab 3</span>
</div>
<div class="content-container">
  <div class="content active">
    <p>THIS IS TAB 1. Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum.</p>
  </div>
  <div class="content">
    <p>THIS IS TAB 2. Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum.</p>
  </div>
  <div class="content">
    <p>THIS IS TAB 3. Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum.</p>
  </div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous">
</script>  

Ответ №3:

Вы можете сделать это следующим образом :

 $('.tabs > span').on('click', function(){
  let ind = $(this).index();
  $('.content > div').removeClass('active').eq(ind).addClass('active');
  $(this).addClass('active-tab').siblings().removeClass('active-tab');
});  
 .tabs span {
  margin: 20px;
  padding: 20px;
  background: black;
  color: white;
  font-weight: 600;
  cursor: pointer;
}

.tabs .active-tab {
  background: #ccc;
  color: black;
}

.content div {
  display: none;
}

.content .active {
  display: block;
}  
 <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous">
</script>

<div class="tabs">
  <span class="tab-1 active-tab">Tab 1</span>
  <span class="tab-2">Tab 2</span>
  <span class="tab-3">Tab 3</span>
</div>
<div class="content">
  <div class="content-1 active">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 1.</p>
  </div>
  <div class="content-2">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 2.</p>
  </div>
  <div class="content-3">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 3.</p>
  </div>
</div>  

Ответ №4:

Вы можете получить индекс элемента, на который вы нажали, и использовать его для изменения класса содержимого с тем же индексом. Имейте в виду, что порядок HTML должен соответствовать порядку вкладок.

 $(".tab").click(function(){
    var index = $(this).index();
    
    $(".content").removeClass("active")
    $(".content:eq(" index ")").addClass("active")
    
    $(".tabs span").removeClass("active-tab")
    $(this).addClass("active-tab")
   
})  
 .tabs span {
    margin: 20px;
    padding: 20px;
    background: black;
    color: white;
    font-weight: 600;
    cursor: pointer;
}

.tabs .active-tab {
    background: #ccc;
    color: black;
}

.content-wrapper div {
    display: none;
}

.content-wrapper .active {
    display: block;
}  
 <div class="tabs">
  <span class="tab active-tab">Tab 1</span>
  <span class="tab">Tab 2</span>
  <span class="tab">Tab 3</span>
</div>
<div class="content-wrapper">
  <div class="content active">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 1.</p>
  </div>
  <div class="content">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 2.</p>
  </div>
  <div class="content">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 3.</p>
  </div>
</div>
<script
    src="https://code.jquery.com/jquery-3.4.1.min.js"
    integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
    crossorigin="anonymous">
</script>  

Ответ №5:

Например, вы могли бы добавить атрибут «data-index» в свои области переключателей вкладок (сопоставив их с желаемыми вкладками «content- $index» или, что еще лучше, идентификаторами), чтобы вы могли передать его в js и легко переключаться между вкладками. Что-то вроде этого:

 <div class="tabs">
  <span class="tab-1 active-tab" data-index="1">Tab 1</span>
  <span class="tab-2" data-index="2">Tab 2</span>
  <span class="tab-3" data-index="3">Tab 3</span>
</div>
<div class="content">
  <div class="content-1 active" id="content-1">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 1.</p>
  </div>
  <div class="content-2" id="content-2">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 2.</p>
  </div>
  <div class="content-3" id="content-3">
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Esse at omnis magni, minus facilis vitae ipsum. THIS IS TAB 3.</p>
  </div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous">
</script>
  
 (function($) {
  const contDiv = $('.content-div');
  const tabsSpan = $('.tabs span');

  /**
   * getContentEl
   * @param index
   * @return {jQuery|HTMLElement}
   */
  function getContentEl(index) {
    return $('#content-'   index);
  }

  /**
   * toggleTab
   * @param e
   * @return {boolean}
   */
  function toggleTab(e) {
    const el = $(e.currentTarget);
    const index = el.attr('data-index');

    getContentEl(index).addClass('active');
    contDiv.removeClass('active');
    tabsSpan.removeClass('active-tab');
    el.addClass('active-tab');

    return true;
  }

  tabsSpan.on('click', toggleTab);
})(jQuery);