Solution
The solution renders the tab headers and content panels from the given JavaScript array, then wires up click handlers so that only one tab's content is visible at a time and the first tab is active by default. Each .tabs container is initialized independently, so multiple tab groups on the same page work correctly.
HTML
Provide an empty container (or one per tab group). The tab headers and content are created by JavaScript from the tabs array.
<section class="tabs" id="tabs-container"></section>
JavaScript
const tabsData = [
{ id: 'tab-1', label: 'Tab 1', content: 'Content for Tab 1' },
{ id: 'tab-2', label: 'Tab 2', content: 'Content for Tab 2' },
{ id: 'tab-3', label: 'Tab 3', content: 'Content for Tab 3' },
];
class Tabs {
constructor(container, tabs) {
this.container = container;
this.tabs = tabs;
this.tabHeaders = [];
this.tabContents = [];
this.render();
}
render() {
this.container.innerHTML = '';
this.container.className = 'tabs';
const headersList = document.createElement('ul');
headersList.className = 'tab-headers';
const contentsWrapper = document.createElement('div');
contentsWrapper.className = 'tab-contents';
this.tabs.forEach((tab, index) => {
const header = document.createElement('li');
header.className = 'tab-header' + (index === 0 ? ' active' : '');
header.textContent = tab.label;
headersList.appendChild(header);
this.tabHeaders.push(header);
const content = document.createElement('div');
content.className = 'tab-content' + (index === 0 ? ' active' : '');
content.textContent = tab.content;
contentsWrapper.appendChild(content);
this.tabContents.push(content);
});
this.container.appendChild(headersList);
this.container.appendChild(contentsWrapper);
this.tabHeaders.forEach((header, index) => {
header.addEventListener('click', () => this.showTab(index));
});
this.showTab(0);
}
showTab(index) {
this.tabHeaders.forEach((header, i) => {
header.classList.toggle('active', i === index);
});
this.tabContents.forEach((content, i) => {
content.classList.toggle('active', i === index);
});
}
}
// Mount into container(s). For multiple tab groups, have multiple empty .tabs elements:
document.querySelectorAll('.tabs').forEach((container) => {
new Tabs(container, tabsData);
});
// Or a single container by id:
// new Tabs(document.getElementById('tabs-container'), tabsData);
Summary
- Class:
Tabsholds the container, tabs data, and references to the created header/content elements. - constructor(container, tabs): Stores container and tabs, then calls
render(). - render(): Builds
ul.tab-headersanddiv.tab-contentsfromthis.tabs, pushes nodes intothis.tabHeadersandthis.tabContents, attaches click handlers, and shows the first tab. - showTab(index): Toggles the
activeclass on the matching header and content so only one tab is visible. - Multiple groups: Create one
Tabsinstance per container (e.g.new Tabs(container, tabsData)), so each tab group runs independently.