Самое первое - отказаться от неоправданного изменения html. Все эти `data-index` - признак плохого кода. Любой блок должен, по возможности, получаться в JS только один раз, записываться в кеш и работать далее с блоком именно как с JS инстансом.
Второе - разделить глобальное управление и каждый таб в отдельности. Каждый логический блок дожлен быть инстансом класса - тогда значительно легче с этим орудовать и дебажить.
Третье - изменения html максимально выносим в отдельный метод.
Ну и вообще - все действия разбить на блоки в виде методов.
Как разультат:
const TabItemSelector = '.pageNav__tabItem';
const ContentItemSelector = '.pageNav__contentItem';
class TabsManager {
constructor(navNode){
this.tabs = [];
this.activeTab = null;
this.initFromHtml(navNode);
this.activateTab(this.tabs[0]);
}
initFromHtml (navNode) {
const headers = navNode.querySelectorAll(TabItemSelector);
const contents = navNode.querySelectorAll(ContentItemSelector);
for (var i = 0; i < headers.length; i++) {
this.registerTab(headers[i], contents[i]);
}
}
registerTab (header, content) {
const tab = new TabItem(header, content);
tab.onActivate(() => this.activateTab(tab));
this.tabs.push(tab);
}
activateTab (tabItem) {
if (this.activeTab) {
this.activeTab.setActive(false);
}
this.activeTab = tabItem;
this.activeTab.setActive(true);
}
}
const ActiveTabHeaderClass = 'pageNav__tabItem--active';
const ActiveTabContentClass = 'pageNav__contentItem--active';
class TabItem {
constructor (header, content) {
this.header = header;
this.content = content;
}
onActivate (action) {
this.header.addEventListener('click', () => action(this));
}
setActive(value) {
this.header.classList.toggle(ActiveTabHeaderClass, value);
this.content.classList.toggle(ActiveTabContentClass, value);
}
}
document.addEventListener('DOMContentLoaded', ()=>{
let tabs = new TabsManager(document.querySelector('.pageNav'));
})
Самое сомнительное в этом коде - это, конечно, TabsManager.initFromHtml, где создается взаимосвязь между headers и contents (к примеру, что будет если заголовков табов будет больше, чем детей?). Но это получается из-за верстки.