Чтобы добавить / удалить класс из элемента, следует использовать методы add()
и remove()
, определенные для classList
.
элемента. См. Комментарии ниже.Это будет работать с любым количеством вкладок, без необходимости изменять JavaScript.
function selectTab(tabIndex) {
let tabContentDivs = document.querySelectorAll(".contentTab"),
tabButtons = document.querySelectorAll(".buttonTab");
// display: none; to all tabContentDivs
for (var i = 0; i < tabContentDivs.length; i++) {
tabContentDivs[i].style.display = 'none';
}
// display: block; to current tab
document.getElementById('tab' + tabIndex + 'Content').style.display = "block";
// remove active class from all buttons
for (var i = 0; i < tabButtons.length; i++) {
tabButtons[i].classList.remove('active');
}
// add active class to current button
document.getElementById('tab' + tabIndex).classList.add('active');
}
.buttonTab {
color: #FFFFFF;
background-color: #333333;
}
.buttonTab.active {
color: #333333;
background-color: #FFFFFF;
}
<button class="buttonTab active" id="tab1" onClick="JavaScript:selectTab(1);">Tab 1</button>
<button class="buttonTab" id="tab2" onClick="JavaScript:selectTab(2);">Tab 2</button>
<br />
<div class="contentTab" id="tab1Content" style="display: block;">
This is the content.
</div>
<div class="contentTab" id="tab2Content" style="display: none;">
This is the content2.
</div>
Но, IMHO, самая большая проблема вашего кода в настоящее время заключается в том, что он слишком функционален.Вы должны указать обратный вызов onclick
для каждой кнопки, и вам также необходимо вручную жестко кодировать tabIndex
.
Почему бы не найти шаблон и подключить кнопки к контейнерам вкладок в зависимости от их положения вих родитель (что вы в любом случае делаете, но жестко программируете, вместо того, чтобы делать это автоматически).
Вот как я думаю, так и должно быть. DRY .
Когда вы работаете с шаблонами, напишите функцию, которая применяет тот же принцип к аналогичным случаям.
В вашем примере id
s на самом деле не требуется.Вы можете иметь отношение 1: 1 к кнопкам и контейнерам и ссылаться на них на основе текущей позиции в родительском (я использовал контейнеры для обеих групп):
function selectTab(tabIndex) {
let tabContentDivs = document.querySelectorAll(".tabContainers > div"),
tabButtons = document.querySelectorAll(".tabButtons > button");
for (var i = 0; i < tabContentDivs.length; i++) {
tabContentDivs[i].removeAttribute('style');
}
document.querySelector('.tabContainers').children[tabIndex].style.display = "block";
for (var i = 0; i < tabButtons.length; i++) {
tabButtons[i].classList.remove('active');
}
document.querySelector('.tabButtons').children[tabIndex].classList.add('active');
}
document.querySelector('.tabButtons').addEventListener('click', function(e) {
let button = e.target.closest('button'),
index = button ? Array.from(button.parentNode.children).indexOf(button) : -1;
if (index > -1)
selectTab(index);
})
.tabButtons button {
color: #FFFFFF;
background-color: #333333;
}
.tabButtons .active {
color: #333333;
background-color: #FFFFFF;
}
.tabContainers>div {
display: none;
}
<div class="tabButtons">
<button class="active">Tab 1</button>
<button>Tab 2</button>
<button>Tab 3</button>
<button>Tab 4</button>
<button>Tab 5</button>
<button>Tab 6</button>
<button>Tab 7</button>
</div>
<div class="tabContainers">
<div style="display: block;">This is the content 1.</div>
<div>This is the content 2.</div>
<div>This is the content 3.</div>
<div>This is the content 4.</div>
<div>This is the content 5.</div>
<div>This is the content 6.</div>
<div>This is the content 7.</div>
</div>
Как правило: всякий раз, когда вы пишете одну и ту же строку кода для двух разных элементов, спросите себя: " CouldЯ делаю так, чтобы этот код использовался в обоих местах?"
Преимущества:
- теперь ваш код легко масштабируется (просто добавьте новые кнопки и новые контейнеры вкладок, и онибудет подключен без необходимости прикасаться к JavaScript)
- вы можете легко добавить новый прослушиватель, чтобы он работал на сенсорных устройствах (вам нужно будет привязать различные события для сенсорных устройств), не изменяяразметка (шаблон HTML).