
В этом тренажере вы попрактикуетесь в создании интерактивных табов (вкладок) с использованием JavaScript и HTML DOM. Вам предстоит работать с HTML-структурой, добавлять и удалять классы, управлять видимостью элементов и обрабатывать события. Задания охватывают различные аспекты создания табов, от простых переключений до более сложных сценариев с динамическим контентом. Каждое задание содержит готовый HTML-код и частично написанный JavaScript-код, который вам нужно будет дополнить.
- Модуль 1: Основы выбора элементов
- Выбор элемента по ID.
- Выбор элементов по классу.
- Выбор элементов по тегу.
- Выбор по селектору CSS.
- Выбор по атрибуту.
- Поиск элементов внутри другого элемента.
- Поиск родительского элемента.
- Поиск соседних элементов (предыдущий, следующий).
- Поиск первого и последнего дочернего элемента.
- Поиск всех дочерних элементов.
- Модуль 2: Манипуляция содержимым
- Модуль 3: Работа с атрибутами
- Модуль 4: Управление классами
- Модуль 5: Управление стилями
- Модуль 6: Создание и удаление элементов
- Создание нового элемента.
- Вставка элемента перед другим элементом.
- Вставка элемента после другого элемента.
- Добавление элемента в определенную позицию внутри списка дочерних элементов.
- Удаление элемента из DOM.
- Замена одного элемента другим.
- Перемещение существующего элемента в другое место DOM..
- Очистка содержимого элемента без его удаления.
- Модуль 7: Обработка событий
- Модуль 8: Работа с формами
- Модуль 9: Продвинутые манипуляции
- Модуль 10: Работа с размерами и прокруткой
- Получение размеров элемента.
- Получение позиции элемента относительно окна браузера.
- Получение позиции элемента относительно родительского элемента.
- Управление прокруткой страницы.
- Определение, виден ли элемент в текущей области просмотра.
- Плавная прокрутка к элементу.
- Создание элемента, который фиксируется при прокрутке.
- Модуль 11: Работа с медиа-элементами
- Модуль 12: Практические задания
Простое переключение табов
Создайте простейшие табы. При клике на заголовок таба, должен отображаться соответствующий контент, а у других табов контент должен скрываться. Изначально активен первый таб.
.tab-content { display: none; } .tab-content.active { display: block; } .tab-header { cursor: pointer; padding: 5px; border: 1px solid #ccc; }
<div class="tabs">
<div class="tab-header">Tab 1</div>
<div class="tab-header">Tab 2</div>
<div class="tab-header">Tab 3</div>
</div>
<div class="tab-contents">
<div class="tab-content active">Content 1</div>
<div class="tab-content">Content 2</div>
<div class="tab-content">Content 3</div>
</div>
const tabHeaders = document.querySelectorAll('.tab-header');
const tabContents = document.querySelectorAll('.tab-content');
tabHeaders.forEach((tabHeader, index) => {
tabHeader.addEventListener(input__1, () => {
tabContents.forEach(content => {
content.classList.input__2('active');
});
tabContents[input__3].classList.add(input__4);
});
});
Добавление активного класса табу
Доработайте предыдущий пример. При клике на заголовок таба, добавьте ему класс 'active', а у других заголовков табов этот класс удалите.
.tab-content { display: none; } .tab-content.active { display: block; } .tab-header { cursor: pointer; padding: 5px; border: 1px solid #ccc; } .tab-header.active { background-color: #eee; }
<div class="tabs">
<div class="tab-header active">Tab 1</div>
<div class="tab-header">Tab 2</div>
<div class="tab-header">Tab 3</div>
</div>
<div class="tab-contents">
<div class="tab-content active">Content 1</div>
<div class="tab-content">Content 2</div>
<div class="tab-content">Content 3</div>
</div>
const tabHeaders = document.querySelectorAll('.tab-header');
const tabContents = document.querySelectorAll('.tab-content');
tabHeaders.forEach((tabHeader, index) => {
tabHeader.addEventListener('click', () => {
tabHeaders.forEach(header => {
header.classList.input__1(input__2);
});
tabHeader.classList.input__3(input__4);
tabContents.forEach(content => {
content.classList.remove('active');
});
tabContents[index].classList.add('active');
});
});
Табы с использованием data-атрибутов
Перепишите логику переключения табов, используя data-атрибуты для связи заголовков табов и контента. Удалите использование индекса.
.tab-content { display: none; } .tab-content.active { display: block; } .tab-header { cursor: pointer; padding: 5px; border: 1px solid #ccc; } .tab-header.active { background-color: #eee; }
<div class="tabs">
<div class="tab-header active" data-tab="1">Tab 1</div>
<div class="tab-header" data-tab="2">Tab 2</div>
<div class="tab-header" data-tab="3">Tab 3</div>
</div>
<div class="tab-contents">
<div class="tab-content active" data-tab="1">Content 1</div>
<div class="tab-content" data-tab="2">Content 2</div>
<div class="tab-content" data-tab="3">Content 3</div>
</div>
const tabHeaders = document.querySelectorAll('.tab-header');
const tabContents = document.querySelectorAll('.tab-content');
tabHeaders.forEach(tabHeader => {
tabHeader.addEventListener('click', () => {
tabHeaders.forEach(header => {
header.classList.remove('active');
});
tabHeader.classList.add('active');
const tabId = tabHeader.dataset.input__1;
tabContents.forEach(content => {
content.classList.remove('active');
});
document.querySelector(`.tab-content[data-tab="${input__2}"]`).classList.add('active');
});
});
Динамическое создание табов
Создайте функцию, которая динамически создает табы на основе массива данных. Функция должна принимать массив объектов, где каждый объект содержит заголовок и контент таба.
.tab-content { display: none; } .tab-content.active { display: block; } .tab-header { cursor: pointer; padding: 5px; border: 1px solid #ccc; } .tab-header.active { background-color: #eee; }
<div class="tabs"></div>
<div class="tab-contents"></div>
function createTabs(tabsData) {
const tabsContainer = document.querySelector('.tabs');
const contentsContainer = document.querySelector('.tab-contents');
tabsData.forEach((tabData, index) => {
const tabHeader = document.input__1('div');
tabHeader.classList.add('tab-header');
tabHeader.textContent = tabData.title;
tabHeader.dataset.tab = index + 1;
tabsContainer.appendChild(tabHeader);
const tabContent = document.createElement('div');
tabContent.classList.add('tab-content');
tabContent.textContent = tabData.content;
tabContent.dataset.tab = index + 1;
if (index === 0) {
tabHeader.classList.add('active');
tabContent.classList.add(input__2);
}
contentsContainer.input__3(tabContent);
});
const tabHeaders = document.querySelectorAll('.tab-header');
tabHeaders.forEach(tabHeader => {
tabHeader.addEventListener('click', () => {
tabHeaders.forEach(header => {
header.classList.remove('active');
});
tabHeader.classList.add('active');
const tabId = tabHeader.dataset.tab;
const tabContents = document.querySelectorAll('.tab-content');
tabContents.forEach(content => {
content.classList.remove('active');
});
document.querySelector(`.tab-content[data-tab="${tabId}"]`).classList.add('active');
});
});
}
const tabsData = [
{ title: 'Tab 1', content: 'Content 1' },
{ title: 'Tab 2', content: 'Content 2' },
{ title: 'Tab 3', content: 'Content 3' }
];
createTabs(tabsData);
Табы с картинками
Создайте табы, где контентом являются картинки. Используйте data-атрибуты.
.tab-content { display: none; width: 300px; height: 300px; } .tab-content.active { display: block; } .tab-header { cursor: pointer; padding: 5px; border: 1px solid #ccc; } .tab-header.active { background-color: #eee; }
<div class="tabs">
<div class="tab-header active" data-tab="1">Tab 1</div>
<div class="tab-header" data-tab="2">Tab 2</div>
<div class="tab-header" data-tab="3">Tab 3</div>
</div>
<div class="tab-contents">
<div class="tab-content active" data-tab="1"><img src="https://naytikurs.ru/assets/uploads/2025/03/3d-modelirovanie-i-vizualizatsiya-test-dlya-spetsialistov-v-trehmernoj-grafike2-300x300.png" alt="" ></div>
<div class="tab-content" data-tab="2"><img src="https://naytikurs.ru/assets/uploads/2025/03/3d-modelirovanie-i-vizualizatsiya-test-dlya-spetsialistov-v-trehmernoj-grafike-300x300.png" alt=""></div>
<div class="tab-content" data-tab="3"><img src="https://naytikurs.ru/assets/uploads/2025/03/3d-modelirovanie-i-vizualizatsiya-test-dlya-spetsialistov-v-trehmernoj-grafike3-300x300.png" alt=""></div>
</div>
const tabHeaders = document.querySelectorAll('.tab-header');
const tabContents = document.querySelectorAll('.tab-content');
tabHeaders.forEach(tabHeader => {
tabHeader.addEventListener('click', () => {
tabHeaders.forEach(header => {
header.classList.remove('active');
});
tabHeader.classList.add(input__1);
const tabId = tabHeader.input__2.tab;
tabContents.forEach(content => {
content.classList.remove('active');
});
document.querySelector(`.tab-content[data-tab="${tabId}"]`).classList.add('active');
});
});
Закрытие табов
Добавьте кнопку 'Закрыть' к каждому табу. При нажатии на кнопку, соответствующий таб (и заголовок, и контент) должен удаляться.
.tab-content { display: none; position: relative; padding: 10px; border: 1px solid #ccc; } .tab-content.active { display: block; } .tab-header { cursor: pointer; padding: 5px; border: 1px solid #ccc; } .tab-header.active { background-color: #eee; } .close-tab { position: absolute; top: 5px; right: 5px; cursor: pointer; }
<div class="tabs">
<div class="tab-header active" data-tab="1">Tab 1</div>
<div class="tab-header" data-tab="2">Tab 2</div>
<div class="tab-header" data-tab="3">Tab 3</div>
</div>
<div class="tab-contents">
<div class="tab-content active" data-tab="1">Content 1 <button class="close-tab">X</button></div>
<div class="tab-content" data-tab="2">Content 2 <button class="close-tab">X</button></div>
<div class="tab-content" data-tab="3">Content 3 <button class="close-tab">X</button></div>
</div>
const tabHeaders = document.querySelectorAll('.tab-header');
const tabContents = document.querySelectorAll('.tab-content');
tabHeaders.forEach(tabHeader => {
tabHeader.addEventListener('click', () => {
tabHeaders.forEach(header => header.classList.remove('active'));
tabHeader.classList.add('active');
const tabId = tabHeader.dataset.tab;
tabContents.forEach(content => content.classList.remove('active'));
document.querySelector(`.tab-content[data-tab="${tabId}"]`).classList.add('active');
});
});
const closeButtons = document.querySelectorAll(input__1);
closeButtons.forEach(button => {
button.addEventListener('click', () => {
const tabContent = button.closest(input__2);
const tabId = tabContent.dataset.tab;
tabContent.input__3();
document.querySelector(`.tab-header[data-tab="${input__4}"]`).remove();
});
});
Ограничение количества табов
Добавьте ограничение на максимальное количество одновременно открытых табов. Если достигнут лимит, новые табы не должны создаваться.
.tab-content { display: none; } .tab-content.active { display: block; } .tab-header { cursor: pointer; padding: 5px; border: 1px solid #ccc; } .tab-header.active { background-color: #eee; }
<div class="tabs"></div>
<div class="tab-contents"></div>
const maxTabs = 3;
function createTabs(tabsData) {
const tabsContainer = document.querySelector('.tabs');
const contentsContainer = document.querySelector('.tab-contents');
tabsData.forEach((tabData, index) => {
if (input__1.querySelectorAll('.tab-header').length >= maxTabs) {
return;
}
const tabHeader = document.createElement('div');
tabHeader.classList.add('tab-header');
tabHeader.textContent = tabData.title;
tabHeader.dataset.tab = index + 1;
tabsContainer.appendChild(tabHeader);
const tabContent = document.createElement('div');
tabContent.classList.add('tab-content');
tabContent.textContent = tabData.content;
tabContent.dataset.tab = index + 1;
if (index === 0) {
tabHeader.classList.add('active');
tabContent.classList.add('active');
}
contentsContainer.appendChild(tabContent);
});
const tabHeaders = document.querySelectorAll('.tab-header');
tabHeaders.forEach(tabHeader => {
tabHeader.addEventListener('click', () => {
tabHeaders.forEach(header => {
header.classList.remove('active');
});
tabHeader.classList.add('active');
const tabId = tabHeader.dataset.tab;
const tabContents = document.querySelectorAll('.tab-content');
tabContents.forEach(content => {
content.classList.remove('active');
});
document.querySelector(`.tab-content[data-tab="${tabId}"]`).classList.add('active');
});
});
}
const tabsData = [
{ title: 'Tab 1', content: 'Content 1' },
{ title: 'Tab 2', content: 'Content 2' },
{ title: 'Tab 3', content: 'Content 3' },
{ title: 'Tab 4', content: 'Content 4' }
];
createTabs(tabsData);