Я написал небольшой скрипт на JavaScript для содержимого вкладок.
(function() {
let contentElms = document.querySelectorAll('.content > div');
let tabs = document.querySelectorAll('.tabs li');
// Show first tab initially
contentElms[0].classList.add("active");
tabs.forEach((tab, index) => {
tab.addEventListener("click", () => {
// Toggle tabs
tabs.forEach((tab) => {
tab.classList.remove("active")
});
tab.classList.add("active");
// Toggle content
contentElms.forEach((el) => {
el.classList.remove("active")
});
contentElms[index].classList.add("active");
});
});
})();
body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
}
body * {
box-sizing: content-box;
}
.tabbed-content {
max-width: 600px;
margin: 10px auto;
}
.tabbed-content .tabs ul {
list-style-type: none;
margin: 0;
padding: 0;
display: flex;
}
.tabbed-content .tabs ul li {
flex: 1;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 4px 4px 0 0;
overflow: hidden;
}
.tabbed-content .tabs ul li.active {
border-bottom: none;
font-weight: bold;
}
.tabbed-content .tabs ul a {
display: block;
padding: 10px;
text-align: center;
text-decoration: none;
color: #7f7f7f;
}
.tabbed-content .content {
padding: 10px;
border: 1px solid rgba(0, 0, 0, 0.1);
border-top: none;
border-radius: 0 0 4px 4px;
}
.tabbed-content .content > div {
font-size: 14px;
line-height: 1.5;
text-align: justify;
display: none;
}
.tabbed-content .content > div.active {
display: block;
}
<div class = "tabbed-content">
<nav class = "tabs">
<ul>
<li class = "active"><a href = "#">Tab 1</a></li>
<li><a href = "#">Tab 2</a></li>
<li><a href = "#">Tab 3</a></li>
</ul>
</nav>
<div class = "content">
<div>Nesciunt velit a hic, officia animi veritatis quis obcaecati tempora omnis iusto.</div>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestias dolorem, sequi quos unde tempora corporis voluptatibus officia atque voluptatum consequuntur necessitatibus fuga quidem nihil. Perspiciatis reiciendis impedit cupiditate odit veritatis!</div>
<div>Deserunt est in, ipsum possimus dolorum! Numquam suscipit laborum, reiciendis delectus. Labore?</div>
</div>
</div>
Вкладки работают нормально.
Меня не устраивает тот факт, что в скрипте есть вложенные forEach
циклы.
forEach
?Какие вложенные циклы вас беспокоят? Цикл верхнего уровня просто назначает обработчик кликов для каждой вкладки. Каждый обработчик кликов не имеет вложенных циклов, только два цикла верхнего уровня для установки класса active
.
@WiktorZychla Могу ли я использовать в сценарии только один цикл forEach
?
Ага. Вы можете использовать этот код
Вместо циклов мы будем сохранять ссылки на активный контент и элементы вкладок и обновлять их при нажатии.
(function() {
let contentElms = document.querySelectorAll('.content > div');
let tabs = document.querySelectorAll('.tabs li');
// Show first tab initially
contentElms[0].classList.add("active");
tabs[0].classList.add("active");
let contentActive = contentElms[0]
let tabActive = tabs[0]
tabs.forEach((tab, index) => {
tab.addEventListener("click", () => {
contentActive.classList.remove("active")
contentActive = contentElms[index]
contentActive.classList.add("active")
tabActive.classList.remove("active")
tabActive = tab
tabActive.classList.add("active")
});
});
})();
body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
}
body * {
box-sizing: content-box;
}
.tabbed-content {
max-width: 600px;
margin: 10px auto;
}
.tabbed-content .tabs ul {
list-style-type: none;
margin: 0;
padding: 0;
display: flex;
}
.tabbed-content .tabs ul li {
flex: 1;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 4px 4px 0 0;
overflow: hidden;
}
.tabbed-content .tabs ul li.active {
border-bottom: none;
font-weight: bold;
}
.tabbed-content .tabs ul a {
display: block;
padding: 10px;
text-align: center;
text-decoration: none;
color: #7f7f7f;
}
.tabbed-content .content {
padding: 10px;
border: 1px solid rgba(0, 0, 0, 0.1);
border-top: none;
border-radius: 0 0 4px 4px;
}
.tabbed-content .content>div {
font-size: 14px;
line-height: 1.5;
text-align: justify;
display: none;
}
.tabbed-content .content>div.active {
display: block;
}
<div class = "tabbed-content">
<nav class = "tabs">
<ul>
<li class = "active"><a href = "#">Tab 1</a></li>
<li><a href = "#">Tab 2</a></li>
<li><a href = "#">Tab 3</a></li>
</ul>
</nav>
<div class = "content">
<div>Nesciunt velit a hic, officia animi veritatis quis obcaecati tempora omnis iusto.</div>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestias dolorem, sequi quos unde tempora corporis voluptatibus officia atque voluptatum consequuntur necessitatibus fuga quidem nihil. Perspiciatis reiciendis impedit cupiditate odit veritatis!</div>
<div>Deserunt est in, ipsum possimus dolorum! Numquam suscipit laborum, reiciendis delectus. Labore?</div>
</div>
</div>
Он не добавляет/удаляет класс «активный» на вкладках.
Хотели бы немного объяснить ваш код, чтобы сообщить ОП, где он сделал ошибку?
@RazvanZamfir все получится
Как уже упоминалось в комментариях, вы можете использовать делегирование событий , чтобы добиться желаемого результата.
(function() {
let contentElms = document.querySelectorAll('.content > div');
let tabsContainer = document.querySelector('.tabs');
// Show first tab initially
contentElms[0].classList.add("active");
tabsContainer.querySelector('li').classList.add("active");
// Use event delegation
tabsContainer.addEventListener("click", (event) => {
let tab = event.target.closest('li');
if (tab) {
let index = Array.from(tabsContainer.querySelectorAll('li')).indexOf(tab);
// Remove active class from all tabs and content
tabsContainer.querySelectorAll('li').forEach(tab => tab.classList.remove("active"));
contentElms.forEach(el => el.classList.remove("active"));
// Add active class to the clicked tab and corresponding content
tab.classList.add("active");
contentElms[index].classList.add("active");
}
});
})();
body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
}
body * {
box-sizing: content-box;
}
.tabbed-content {
max-width: 600px;
margin: 10px auto;
}
.tabbed-content .tabs ul {
list-style-type: none;
margin: 0;
padding: 0;
display: flex;
}
.tabbed-content .tabs ul li {
flex: 1;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 4px 4px 0 0;
overflow: hidden;
}
.tabbed-content .tabs ul li.active {
border-bottom: none;
font-weight: bold;
}
.tabbed-content .tabs ul a {
display: block;
padding: 10px;
text-align: center;
text-decoration: none;
color: #7f7f7f;
}
.tabbed-content .content {
padding: 10px;
border: 1px solid rgba(0, 0, 0, 0.1);
border-top: none;
border-radius: 0 0 4px 4px;
}
.tabbed-content .content > div {
font-size: 14px;
line-height: 1.5;
text-align: justify;
display: none;
}
.tabbed-content .content > div.active {
display: block;
}
<div class = "tabbed-content">
<nav class = "tabs">
<ul>
<li class = "active"><a href = "#">Tab 1</a></li>
<li><a href = "#">Tab 2</a></li>
<li><a href = "#">Tab 3</a></li>
</ul>
</nav>
<div class = "content">
<div>Nesciunt velit a hic, officia animi veritatis quis obcaecati tempora omnis iusto.</div>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestias dolorem, sequi quos unde tempora corporis voluptatibus officia atque voluptatum consequuntur necessitatibus fuga quidem nihil. Perspiciatis reiciendis impedit cupiditate odit veritatis!</div>
<div>Deserunt est in, ipsum possimus dolorum! Numquam suscipit laborum, reiciendis delectus. Labore?</div>
</div>
</div>
Итак, tabsContainer
(родительский элемент всех вкладок) прослушивает события кликов. При щелчке проверяется, является ли цель (event.target)
вкладкой (li)
. Затем индекс выбранной вкладки определяется путем преобразования NodeList
вкладок в массив с помощью Array.from
и использования indexOf
для поиска индекса. Наконец, из всех вкладок и элементов контента сначала удаляется класс active
. Затем выбранная вкладка и соответствующий контент становятся активными.
Я не уверен, какой из них быстрее: мой или ответ , опубликованный выше , но я предполагаю, что оба варианта дадут одинаковый результат. Если вас волнует временная сложность, вам нужно проверить, какой из них работает быстрее.
временная сложность"??? Действительно? Вы ожидаете миллионы вкладок?
@jabaa извини, но как человека, обладающего знаниями в области искусственного интеллекта, меня волнует временная сложность всего. :)
Похоже, вы не понимаете временную сложность, если вы думаете, в данном случае об этом следует упомянуть. В случаях с небольшими n
временная сложность не имеет значения. Худшая временная сложность может быть быстрее, чем лучшая временная сложность.
Да, никаких петель вообще не нужно. Используйте делегирование событий и сохраните текущую активную вкладку в переменную.