Ванильный Javascript показывает вкладку и скрывает другие

#javascript #tabs

#javascript #вкладки

Вопрос:

прямо сейчас я воссоздаю элемент начальной загрузки «Переключаемые / динамические вкладки» (вы можете найти его там — https://www.w3schools.com/bootstrap4/bootstrap_navs.asp ) но я не могу запустить свой контент. «Вкладки» работают так, как задумано, но я не знаю, как заставить их показывать содержимое после щелчка, как я хотел. Я хочу, чтобы они отображали «связанный» div при нажатии и скрывали divs, связанные с другими кнопками. Точно так же, как элемент bootstrap. Большое вам спасибо!

У меня есть что-то вроде этого:http://jsfiddle.net/Darlington/9kjst3rp/8

 let tabs = Array.from(document.querySelectorAll('.subnavBtn'));

const handleClick = (e) => {
  e.preventDefault();
  tabs.forEach(node => {
    node.classList.remove('active-btn');
  });
  e.currentTarget.classList.add('active-btn');

}

tabs.forEach(node => {
  node.addEventListener('click', handleClick)
});  
 .subnavDiv {
  display: none;
}

.active {
  display: block;
}

.active-btn {
  background-color: red;
}  
 <nav class="subnav">
 <button class="subnavBtn">
   Button 1
 </button>

 <button class="subnavBtn">
   Button 2
 </button>

 <button class="subnavBtn">
   Button 3
 </button>
</nav>

<!-- DIVS I WANT TO SHOW -->

<div class="subnavDiv active">
Content 1
</div>

<div class="subnavDiv">
Content 2
</div>

<div class="subnavDiv">
Content 3
</div>  

Комментарии:

1. кажется, это основная проблема, я предполагаю, что здесь уже существуют решения. В принципе, вы можете добавить идентификатор типа «tab-1» и «contentTab-1″ для запроса соответствующего tabContent или вы можете назвать атрибут как data-tab-content =»1» в качестве опции вашего запроса

Ответ №1:

Вы можете сделать это в следующих шагах

  • Сохраняйте все разделы (содержимое) в массиве в глобальной области видимости
  • Передайте вторую переменную btn для handleClick
  • В forEach() отправьте элемент текущего индекса в handleClick в качестве второго параметра
  • Внутри handleClick удалить active класс из всех разделов
  • Наконец, добавьте active класс в btn (второй параметр функции)

 let tabs = Array.from(document.querySelectorAll('.subnavBtn'));
let contents = Array.from(document.querySelectorAll('.subnavDiv'));


const handleClick = (e,btn) => {
  e.preventDefault();
  tabs.forEach(node => {
    node.classList.remove('active-btn');
  });
  e.currentTarget.classList.add('active-btn');
  contents.forEach(x => x.classList.remove('active'))
  btn.classList.add('active');

}

tabs.forEach((node,i) => {
  node.addEventListener('click',(e) => handleClick(e,contents[i]))
});  
 .subnavDiv {
  display: none;
}

.active {
  display: block;
}

.active-btn {
  background-color: red;
}  
 <nav class="subnav">
 <button class="subnavBtn">
   Button 1
 </button>

 <button class="subnavBtn">
   Button 2
 </button>

 <button class="subnavBtn">
   Button 3
 </button>
</nav>

<!-- DIVS I WANT TO SHOW -->

<div class="subnavDiv active">
Content 1
</div>

<div class="subnavDiv">
Content 2
</div>

<div class="subnavDiv">
Content 3
</div>  

Ответ №2:

Ответ @Maheer Ali прекрасен, вот альтернатива, использующая атрибуты данных, чтобы указать, какая вкладка связана с каждой кнопкой:

 const buttons = document.querySelectorAll('.subnavBtn');
const divs = document.querySelectorAll('.subnavDiv');

const handleClick = e => {
  e.preventDefault();
  
  // Buttons
  buttons.forEach(node => node.classList.remove('active-btn'));
  e.currentTarget.classList.add('active-btn');
  
  // Divs (tabs)
  divs.forEach(node => node.classList.remove('active'));
  [...divs].filter(div => div.dataset.tab === e.currentTarget.dataset.tab)[0].classList.add('active');
}

buttons.forEach(node => node.addEventListener('click', handleClick));  
 .subnavDiv { display: none; }
.active { display: block; }
.active-btn { background-color: red; }  
 <nav class="subnav">
 <button class="subnavBtn active-btn" data-tab="1">Button 1</button>
 <button class="subnavBtn" data-tab="2">Button 2</button>
 <button class="subnavBtn" data-tab="3">Button 3</button>
</nav>

<div class="subnavDiv active" data-tab="1">Content 1</div>
<div class="subnavDiv" data-tab="2">Content 2</div>
<div class="subnavDiv" data-tab="3">Content 3</div>