问题
I've been trying to create tabs in JavaScript. When clicking on a new tab the active class should be applied to it as well as its associated panel content should be displayed. However, the active class isn't being applied when another tab is clicked and the panels are not changing either, they are just stacking on top of each other.
const tabs = document.querySelector(".tabs");
const active = document.querySelector(".active");
const panel = document.querySelector(".panel");
function onTabClick(event) {
// deactivate existing active tabs and panel
active.classList.remove('.active');
for (let i = 0; i < panel.length; i++) {
panel[i].style.display = "none";
}
// activate new tabs and panel
event.target.classList.add('.active');
let classString = event.target.innerHTML;
console.log(classString);
document.getElementsByClassName(classString)[0].style.display = "block";
}
tabs.addEventListener('click', onTabClick, false);
.tabs {
display: flex;
justify-content: space-around;
margin: 20px 2px 40px 2px;
height: 40px;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.2);
}
.tabs>* {
width: 100%;
color: dimgray;
height: 100%;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
.tabs>*:hover:not(.active) {
background-color: rgb(220, 220, 220);
}
.tabs>.active {
color: white;
background-color: #4CAF50;
}
.panel {
display: none;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div class="tabs">
<div class="tab active">List</div>
<div class="tab">Grid</div>
<div class="tab">something</div>
</div>
<div class="Lists panel" style='display:block'>
panel 1 text
</div>
<div class="Grid panel">
panel 2 text
</div>
<div class="something panel">
panel 3 text
</div>
</body>
</html>
回答1:
In your JavaScript when getting all the elements of a specific class, document.querySelecto(".className")
only grabs the first element with the given class. To get all the elements, you'll have to use document.querySelectorAll(".className")
.
Then when adding or removing a class from an element, you don't put the point before the class name. So instead of tab[i].classList.remove(".active");
, it should be tab[i].classList.remove("active");
.
Also, instead of explicity hiding the panel elements, I used an active
class which will be applied to panel associated tab.
Finally, you should not use the tab text as the class name for the respective panel. This would be problematic when you have multiple words in the tab text. What I did was use the data attribute of the tabs to specify the relative class of the panel and place all the panels in a div
element .panels
. Now you can put what ever text you want in the tabs and using the data-target
attribute, place the class name for the panel.
JavaScript
const tabs = document.querySelectorAll(".tabs");
const tab = document.querySelectorAll(".tab");
const panel = document.querySelectorAll(".panel");
function onTabClick(event) {
// deactivate existing active tabs and panel
for (let i = 0; i < tab.length; i++) {
tab[i].classList.remove("active");
}
for (let i = 0; i < panel.length; i++) {
panel[i].classList.remove("active");
}
// activate new tabs and panel
event.target.classList.add('active');
let classString = event.target.getAttribute('data-target');
console.log(classString);
document.getElementById('panels').getElementsByClassName(classString)[0].classList.add("active");
}
for (let i = 0; i < tab.length; i++) {
tab[i].addEventListener('click', onTabClick, false);
}
CSS
.tabs {
display: flex;
justify-content: space-around;
margin: 20px 2px 40px 2px;
height: 40px;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.2);
}
.tabs>* {
width: 100%;
color: dimgray;
height: 100%;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
.tabs>*:hover:not(.active) {
background-color: rgb(220, 220, 220);
}
.tabs>.active {
color: white;
background-color: #4CAF50;
}
.panel {
display: none;
}
.panel.active {
display: block;
}
HTML
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div class="tabs">
<div class="tab active" data-target="Lists">Lists</div>
<div class="tab" data-target="Grid">Grid</div>
<div class="tab" data-target="Something">Something</div>
</div>
<div id="panels">
<div class="Lists panel active">
panel 1 text
</div>
<div class="Grid panel">
panel 2 text
</div>
<div class="Something panel">
panel 3 text
</div>
</div>
</body>
</html>
来源:https://stackoverflow.com/questions/54723528/how-to-create-tabs-in-javascript