Сегодня разберем как делаются вкладки (табы) на JQuery и JavaScript .
Весь код для копирования в конце статьи.
Можете посмотреть демо чтобы увидеть как будет выглядеть результат. В колонке JS сверху расположен код JQuery, ниже JavaScript.
В самом начале объясню схему, по которой мы будем делать табы:
- Добавим вкладкам и блокам с их содержимым классы с приставкой js- для обращения к ним из JavaScript.
- Добавим data атрибут data-tab для идентификации наших табов. Некоторые делают табы по индексу элемента в dom-дереве, я так делать не буду, это не гибкая конструкция.
- При клике на вкладку, удалим активный класс у всех вкладок, добавим той, по которой кликнули, удалим активный класс у всех блоков с содержимым и добавим тому, у которого значение атрибута 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
});
- Получили значение атрибута data-tab у текущего элемента
- Здесь происходит конкатенация (соединение) строк. В селекторе 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
});
- Удалили класс active у активной вкладки
- Добавили класс active вкладке по которой кликнули
- Удалили класс active у активного контейнера с содержимым
- Добавили класс 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
// клик!
});
});
- Циклом перебираем элементы в массива. В массиве у нас лежат dom-элементы, то есть наши вкладки.
- Каждому элементу добавляем функцию-обработчик при событии клика.
Теперь в функции-обработчике объявим несколько переменных для удобной манипуляции. Все можно сделать и без переменных, но мы будем делать по-хорошему.
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
- Получаем идентификатор вкладки.
- Ищем контейнер с таким же значением атрибута data-tab.
- Ищем активную вкладку.
- Ищем активный контейнер.
В заключении поработаем с классами:
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
});
});
- Удалили класс active у активной вкладки
- Добавили класс active вкладке по которой кликнули
- Удалили класс active у активного блока с содержимым
- Добавили класс 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');
});
});
Канал о фрилансе
Там я делюсь фишками о фрилансе: деньги, клиенты, автоматизация, фриланс. Раньше это был закрытый материал с платным доступом. Сейчас он открыт. Иногда подписчикам будет открываться платные материалы. Подписаться
1 комментарий
document.addEventListener(‘scroll’, function () {
if ($(window).scrollTop() > 1000))<—?????? зачем эту скобку {
$('.js-header-fixed').addClass('is-show');
} else {
$('.js-header-fixed').removeClass('is-show');
}
})