有没有比这更好的方法来使用vanilla JavaScript创建选项卡?



我正在尝试使用HTML按钮和vanilla JavaScript在网页中创建选项卡。我想出了这个解决方案:

const tab1 = document.getElementById("tab-1");
const tab2 = document.getElementById("tab-2");
const tab3 = document.getElementById("tab-3");
const tabs = [tab1, tab2, tab3];
const tab1Content = document.getElementById("tab-1-content");
const tab2Content = document.getElementById("tab-2-content");
const tab3Content = document.getElementById("tab-3-content");
const tabContents = [tab1Content, tab2Content, tab3Content];
tab1.addEventListener("click", () => {displayTab(tab1, tab1Content)});
tab2.addEventListener("click", () => {displayTab(tab2, tab2Content)});
tab3.addEventListener("click", () => {displayTab(tab3, tab3Content)});
function displayTab(tab, tabContent) {
for (let i = 0; i < tabs.length; i++) {
if (tabs[i].classList.contains("active")) {
tabs[i].classList.remove("active");
tabContents[i].classList.add("hide");
}
}
tab.classList.add("active");
tabContent.classList.remove("hide");
}
.hide { display: none }
.active { font-weight : bold }
<h1>Tabs</h1>
<div class="tabBtns">
<button id="tab-1" class="active">Tab 1</button>
<button id="tab-2">Tab 2</button>
<button id="tab-3">Tab 3</button>
</div>
<div class="content">
<div id="tab-1-content">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Dignissimos qui labore, quam dicta voluptate
libero est blanditiis perspiciatis voluptatibus perferendis velit repudiandae. Maxime, eligendi. Vitae
magnam similique harum sunt quibusdam.
</div>
<div id="tab-2-content" class="hide">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Dolores similique assumenda reprehenderit eaque
itaque in magni vero repudiandae, totam maiores saepe iste culpa labore quam esse ipsam fugit cupiditate
facilis sunt aliquid ad sit voluptatibus veritatis non. Eligendi accusantium libero veniam facere, expedita,
magnam quia assumenda similique quas, voluptatum nostrum.
</div>
<div id="tab-3-content" class="hide">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Culpa, sunt?
</div>
</div>

有没有更有效的方法呢?感觉可能有点多余,必须手动将每个选项卡及其内容添加到各自的数组中,然后还必须手动将事件侦听器应用于每个选项卡。如果可能的话,我将不胜感激一个更优雅的解决方案。

遍历所有选项卡,并在单击按钮时隐藏它们。找到 单击按钮的索引,您可以访问关联的<div>,无需 ID。

const contents = document.querySelectorAll('.content > div');
const buttons = document.querySelectorAll('.tabBtns button');
buttons.forEach((button, i) => {
button.addEventListener('click', () => {
buttons.forEach(button => button.classList.remove('active'));
contents.forEach(content => content.classList.add('hide'));
button.classList.add('active');
contents[i].classList.remove('hide');
});
});
.active {
background-color: yellow;
}
.hide {
display: none;
}
<h1>Tabs</h1>
<div class="tabBtns">
<button class="active">Tab 1</button>
<button>Tab 2</button>
<button>Tab 3</button>
</div>
<div class="content">
<div>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Dignissimos qui labore, quam dicta voluptate libero est blanditiis perspiciatis voluptatibus perferendis velit repudiandae. Maxime, eligendi. Vitae magnam similique harum sunt quibusdam.
</div>
<div class="hide">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Dolores similique assumenda reprehenderit eaque itaque in magni vero repudiandae, totam maiores saepe iste culpa labore quam esse ipsam fugit cupiditate facilis sunt aliquid ad sit voluptatibus
veritatis non. Eligendi accusantium libero veniam facere, expedita, magnam quia assumenda similique quas, voluptatum nostrum.
</div>
<div class="hide">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Culpa, sunt?
</div>
</div>

您还可以将上次单击的按钮的索引保存在持久变量中,而不是循环访问单击处理程序中的每个元素。

你可以做一个小函数来构建你的标签

function buildTab(content, number, etc...) {
const tab = document.createElement("div")
tab.innerHTML = content
tab.addEventListener...
// whatever else you wanna do
return tab
}
//json containing all the content you wanna display(?)
const tabs = contentArray.map(c => buildTab(...c))

你可以用

  • 事件委派
  • 数据属性
  • 您还必须使用classList.toggle()方法及其布尔选项addremoveclass

const buttonsParent   = document.querySelector('div#tab-Btns')
,   all_tab_elms    = document.querySelectorAll('button[data-tab], div[data-tab]')
;
buttonsParent.onclick = ({target}) =>
{
if (!target.matches('button[data-tab]')) return  // ignore other click in this area (like spaces between buttons)

all_tab_elms.forEach( elTab => elTab.classList
.toggle('active', (elTab.dataset.tab===target.dataset.tab )))
}
button[data-tab].active { font-weight: bold; }
div[data-tab]           { display: none;     }
div[data-tab].active    { display: block;    }
<h1>Tabs</h1>
<div id="tab-Btns">
<button data-tab="tab-1" class="active">Tab 1</button>
<button data-tab="tab-2">Tab 2</button>
<button data-tab="tab-3">Tab 3</button>
</div>
<div id="tab-content">
<div data-tab="tab-1" class="active">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Dignissimos qui labore, quam dicta voluptate
libero est blanditiis perspiciatis voluptatibus perferendis velit repudiandae. Maxime, eligendi. Vitae
magnam similique harum sunt quibusdam.
</div>
<div data-tab="tab-2">
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Dolores similique assumenda reprehenderit eaque
itaque in magni vero repudiandae, totam maiores saepe iste culpa labore quam esse ipsam fugit cupiditate
facilis sunt aliquid ad sit voluptatibus veritatis non. Eligendi accusantium libero veniam facere, expedita,
magnam quia assumenda similique quas, voluptatum nostrum.
</div>
<div data-tab="tab-3">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Culpa, sunt?
</div>
</div>

最新更新