← Назад в «Блог»
12 364

Табы на JQuery и JavaScript


Сегодня разберем как делаются вкладки (табы) на JQuery и JavaScript .

Весь код для копирования в конце статьи.

Можете посмотреть демо чтобы увидеть как будет выглядеть результат. В колонке JS сверху расположен код JQuery, ниже JavaScript.

В самом начале объясню схему, по которой мы будем делать табы:

  1. Добавим вкладкам и блокам с их содержимым классы с приставкой js- для обращения к ним из JavaScript.
  2. Добавим data атрибут data-tab для идентификации наших табов. Некоторые делают табы по индексу элемента в dom-дереве, я так делать не буду, это не гибкая конструкция.
  3. При клике на вкладку, удалим активный класс у всех вкладок, добавим той, по которой кликнули, удалим активный класс у всех блоков с содержимым и добавим тому, у которого значение атрибута data-tab такое же как у атрибута data-tab нашей вкладки.

Про приставку js.
Мы добавляем отдельный класс для манипуляций из js потому что, на один класс могут быть завязаны стили, которые в дальнейшем могут быть заменены. Приставка js даст вам или другому разработчику понять что этот элемент, в частности класс, участвует в интерактивности, на нем завязаны только события javascript. Таким образом этот класс всегда будет у элемента, не смотря на стили.

В нескольких проектах я это правило игнорировал и потом на исправление багов я тратил время.

Первым делом создадим разметку для наших табов.

<!-- Общий контейнер для табов -->
<div class="tabs">
   
   <!--  Контейнер с вкладками   -->
   <ul class="tab-header">
      <li class="tab-header__item js-tab-trigger active" data-tab="1">Первая</li>
      <li class="tab-header__item js-tab-trigger" data-tab="2">Вторая</li>
      <li class="tab-header__item js-tab-trigger" data-tab="3">Третья</li>
   </ul>
   
   <!--  Контейнер с блоками, которые содержат контент вкладок   -->
   <ul class="tab-content">
      <li class="tab-content__item js-tab-content active" data-tab="1">
         Далеко-далеко за словесными, горами в стране гласных и согласных живут рыбные тексты.
      </li>
      <li class="tab-content__item js-tab-content" data-tab="2">
         Lorem ipsum, dolor sit amet consectetur adipisicing elit. Dolorum rem laboriosam cum repudiandae natus corrupti?
      </li>
      <li class="tab-content__item js-tab-content" data-tab="3">
         Далеко-далеко за словесными горами.
      </li>
   </ul>
</div>

Первой вкладке и её содержимому мы добавили класс active, чтобы по-умолчанию эти два элемента были активны. Остальные вкладки оставляем неактивными, а блоки с контентом скрываем.

Стили:

.tabs {
   width: 100%;
   max-width: 500px;
}

/* Стили для списка вкладок */
.tab-header {
   list-style: none;
   padding-left: 0;
   display: flex;
   align-items: center;
   justify-content: flex-start;
   margin: 0;
}

/* Стили для вкладки */
.tab-header__item {
   padding: 10px 20px;
   margin-right: 5px;
   cursor: pointer;
   border: 1px solid #ddd;
}

/* Стили для активной вкладки */
.tab-header__item.active {
   color: red;
   border-bottom: none;
   position: relative;
   background-color: #fff;
}

/* Стиль для списка контейнеров с содержимым вкладок */
.tab-content {
   list-style: none;
   padding: 0;
   margin: 0;
}

/* Стили для контейнера с содержимым вкладки. По умолчанию скрыт. */
.tab-content__item {
   display: none;
   padding: 20px;
   border: 1px solid #ddd;
   margin-top: -1px;
}

/* Стили для активного контейнера вкладки */
.tab-content__item.active {
   display: block;
}

Стилизовать — дело вкуса, если вы не против я стилизовал на свой вкус.

Здесь мы определили вид наших вкладок и контенеров с содержимым. Важным для понимания будут стили для вкладок, активной вкладки, контенеров, активного контейнера.

Тут все довольно просто. Активной вкладке добавляем изменение цвета, остальные остаются с серым цветом. Активный блок показываем, остальные скрываем.

Разберем Jquery код:

Итак, первое что нужно сделать, обработак клик по каждому элементу.

$('.js-tab-trigger').click(function() {
     // клик! 
})

Теперь нам нужно получить идентификатор нашей вкладки и найти контент с таким же значением data-tab.

$('.js-tab-trigger').click(function() {
   var id = $(this).attr('data-tab'), // 1
       content = $('.js-tab-content[data-tab="'+ id +'"]'); // 2
});
  1. Получили значение атрибута data-tab у текущего элемента
  2. Здесь происходит конкатенация (соединение) строк. В селекторе jquery мы разрываем строку и вставляем туда значение нашей переменной id с помощью операторов сложения «+». Если вы складываете строки, оператор «+» соединит их. В результате конкатенации строк мы получили такой селектор: ‘.js-tab-content[data-tab="3″]’ (содержимое data-tab меняется в зависимости от вкладки).
    Подробнее здесь.

Отлично, теперь мы знаем и вкладку по которой мы кликнули и контейнер с содержимым этой вкладки. Теперь дело за малым, поработать с классами. Дополним наш предыдущий код.


$('.js-tab-trigger').click(function() {
   var id = $(this).attr('data-tab'),
       content = $('.js-tab-content[data-tab="'+ id +'"]');
   
   $('.js-tab-trigger.active').removeClass('active'); // 1
   $(this).addClass('active'); // 2
   
   $('.js-tab-content.active').removeClass('active'); // 3
   content.addClass('active'); // 4
});
  1. Удалили класс active у активной вкладки
  2. Добавили класс active вкладке по которой кликнули
  3. Удалили класс active у активного контейнера с содержимым
  4. Добавили класс active контейнеру который должен быть активным

Вот и все, код на JQuery занял у нас всего лишь 10 строк кода. Рассмотрим JavaSсript.

Код на JavaScript не сложнее чем jquery код. Когда я начинал знакомиться с JQuery, в одном из проектов она не хотела работать, там была сложная структура битрикс сайта и я потратил много времени чтобы заставить её работать. После безрезультатных попыток я психанул и написал табы на JavaScript, до этого я боялся его, но написав табы без JQuery удивился, это не так сложно как кажется.

Разберем JavaScript код:

Прежде чес обработать клик по вкладке, объявим несколько переменных для наших вкладок и контенеров с содержимым.

var jsTriggers = document.querySelectorAll('.js-tab-trigger'),
    jsContents = document.querySelectorAll('.js-tab-content');

Теперь можно обработать клик по вкладкам.

jsTriggers.forEach(function(trigger) { // 1
   trigger.addEventListener('click', function() { // 2
      // клик!
   });
});
  1. Циклом перебираем элементы в массива. В массиве у нас лежат dom-элементы, то есть наши вкладки.
  2. Каждому элементу добавляем функцию-обработчик при событии клика.

Теперь в функции-обработчике объявим несколько переменных для удобной манипуляции. Все можно сделать и без переменных, но мы будем делать по-хорошему.

var id = this.getAttribute('data-tab'), // 1
    content = document.querySelector('.js-tab-content[data-tab="'+id+'"]'), // 2
    activeTrigger = document.querySelector('.js-tab-trigger.active'), // 3
    activeContent = document.querySelector('.js-tab-content.active'); // 4
  1. Получаем идентификатор вкладки.
  2. Ищем контейнер с таким же значением атрибута data-tab.
  3. Ищем активную вкладку.
  4. Ищем активный контейнер.

В заключении поработаем с классами:

var jsTriggers = document.querySelectorAll('.js-tab-trigger'),
    jsContents = document.querySelectorAll('.js-tab-content');

jsTriggers.forEach(function(trigger) {
   trigger.addEventListener('click', function() {
      var id = this.getAttribute('data-tab'),
          content = document.querySelector('.js-tab-content[data-tab="'+id+'"]'),
          activeTrigger = document.querySelector('.js-tab-trigger.active'),
          activeContent = document.querySelector('.js-tab-content.active');
      
      activeTrigger.classList.remove('active'); // 1
      trigger.classList.add('active'); // 2
      
      activeContent.classList.remove('active'); // 3
      content.classList.add('active'); // 4
   });
});
  1. Удалили класс active у активной вкладки
  2. Добавили класс active вкладке по которой кликнули
  3. Удалили класс active у активного блока с содержимым
  4. Добавили класс active контейнеру который должен быть активным

Итоговый код

HTML

<!-- Общий контейнер для табов -->
<div class="tabs">
   
   <!--  Контейнер с вкладками   -->
   <ul class="tab-header">
      <li class="tab-header__item js-tab-trigger active" data-tab="1">Первая</li>
      <li class="tab-header__item js-tab-trigger" data-tab="2">Вторая</li>
      <li class="tab-header__item js-tab-trigger" data-tab="3">Третья</li>
   </ul>
   
   <!--  Контейнер с блоками, которые содержат контент вкладок   -->
   <ul class="tab-content">
      <li class="tab-content__item js-tab-content active" data-tab="1">
         Далеко-далеко за словесными, горами в стране гласных и согласных живут рыбные тексты.
      </li>
      <li class="tab-content__item js-tab-content" data-tab="2">
         Lorem ipsum, dolor sit amet consectetur adipisicing elit. Dolorum rem laboriosam cum repudiandae natus corrupti?
      </li>
      <li class="tab-content__item js-tab-content" data-tab="3">
         Далеко-далеко за словесными горами.
      </li>
   </ul>
</div>

CSS

.tabs {
   width: 100%;
   max-width: 500px;
}

/* Стили для списка вкладок */
.tab-header {
   list-style: none;
   padding-left: 0;
   display: flex;
   align-items: center;
   justify-content: flex-start;
   margin: 0;
}

/* Стили для вкладки */
.tab-header__item {
   padding: 10px 20px;
   margin-right: 5px;
   cursor: pointer;
   border: 1px solid #ddd;
}

/* Стили для активной вкладки */
.tab-header__item.active {
   color: red;
   border-bottom: none;
   position: relative;
   background-color: #fff;
}

/* Стиль для списка контейнеров с содержимым вкладок */
.tab-content {
   list-style: none;
   padding: 0;
   margin: 0;
}

/* Стили для контейнера с содержимым вкладки. По умолчанию скрыт. */
.tab-content__item {
   display: none;
   padding: 20px;
   border: 1px solid #ddd;
   margin-top: -1px;
}

/* Стили для активного контейнера вкладки */
.tab-content__item.active {
   display: block;
}

jQuery или

Не забудьте подключить библиотеку jQuery. Я подключаю через cdnjs — https://cdnjs.com/libraries/jquery

$('.js-tab-trigger').click(function() {
   var id = $(this).attr('data-tab'),
       content = $('.js-tab-content[data-tab="'+ id +'"]');
   
   $('.js-tab-trigger.active').removeClass('active');
   $(this).addClass('active');
   
   $('.js-tab-content.active').removeClass('active');
   content.addClass('active');
});

JavaScript

var jsTriggers = document.querySelectorAll('.js-tab-trigger'),
    jsContents = document.querySelectorAll('.js-tab-content');

jsTriggers.forEach(function(trigger) {
   trigger.addEventListener('click', function() {
      var id = this.getAttribute('data-tab'),
          content = document.querySelector('.js-tab-content[data-tab="'+id+'"]'),
          activeTrigger = document.querySelector('.js-tab-trigger.active'),
          activeContent = document.querySelector('.js-tab-content.active');
      
      activeTrigger.classList.remove('active');
      trigger.classList.add('active');
      
      activeContent.classList.remove('active');
      content.classList.add('active');
   });
});
Полезно
33
1
Непонятно
19
Поделиться
Отправить
Линкануть
Вотсапнуть

Канал о фрилансе

Там я делюсь фишками о фрилансе: деньги, клиенты, автоматизация, фриланс. Раньше это был закрытый материал с платным доступом. Сейчас он открыт. Иногда подписчикам будет открываться платные материалы. Подписаться

← Назад в «Блог»

1 комментарий

document.addEventListener(‘scroll’, function () {
if ($(window).scrollTop() > 1000))<—?????? зачем эту скобку {
$('.js-header-fixed').addClass('is-show');
} else {
$('.js-header-fixed').removeClass('is-show');
}
})

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *