1

hi guys i have this code s of tabbed component that most of you familiar with . the problem is that when i click on certain tab i want to other tabs get hidden

const tab = document.querySelectorAll(".tab");
const tabContainer = document.querySelector(".upContainer");

tabContainer.addEventListener("click", function(e) {

  const clicked = e.target.closest(".tab").textContent;

  document
    .querySelector(`.content__${clicked}`)
    .classList.remove("hidden");
});
.container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100vh;
  align-items: center;
  justify-content: center;
}

.upContainer {
  display: flex;
}

.tab {
  width: 100px;
  height: 70px;
  background-color: aqua;
  cursor: pointer;
  text-align: center;
  margin: 0px 10px;
}

.content {
  width: 300px;
  height: 100px;
  margin-top: 10px;
  text-align: center;
  background-color: black;
  color: aliceblue;
}

.hidden {
  display: none;
}
<div class="container">
  <div class="upContainer">
    <div class="tab1 tab">tab1</div>
    <div class="tab2 tab">tab2</div>
    <div class="tab3 tab">tab3</div>
  </div>
  <div class="downContainer">
    <div class="content__tab1 content">content1</div>
    <div class="content__tab2 content hidden">content2</div>
    <div class="content__tab3 content hidden">content3</div>
  </div>
</div>
Andy
  • 61,948
  • 13
  • 68
  • 95

3 Answers3

1

Consider toggling the other tab content containers' back to hidden when you change the active one to be shown.

const tab = document.querySelectorAll(".tab");
const tabContainer = document.querySelector(".upContainer");
const tabContents = document.querySelectorAll(".content");

tabContainer.addEventListener("click", function(e) {
  const clicked = e.target.closest(".tab").textContent;

  tabContents.forEach((content) => {
    content.classList.toggle('hidden', !content.matches(`.content__${clicked}`));
  });
});
.container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100vh;
  align-items: center;
  justify-content: center;
}

.upContainer {
  display: flex;
}

.tab {
  width: 100px;
  height: 70px;
  background-color: aqua;
  cursor: pointer;
  text-align: center;
  margin: 0px 10px;
}

.content {
  width: 300px;
  height: 100px;
  margin-top: 10px;
  text-align: center;
  background-color: black;
  color: aliceblue;
}

.hidden {
  display: none;
}
<div class="container">
  <div class="upContainer">
    <div class="tab1 tab">tab1</div>
    <div class="tab2 tab">tab2</div>
    <div class="tab3 tab">tab3</div>
  </div>
  <div class="downContainer">
    <div class="content__tab1 content">content1</div>
    <div class="content__tab2 content hidden">content2</div>
    <div class="content__tab3 content hidden">content3</div>
  </div>
</div>
Wongjn
  • 8,544
  • 2
  • 8
  • 24
0

Here's a CSS-only solution (mostly for reference, since JS is preferred):

You have multiple .content elements and you only want one of them to be shown at a time. This is exactly the same as how radio buttons work: One checked at a time.

Using that, we can add some <label>s and <input type="radio">s:

<div class="container">
  <div class="upContainer">
    <label for="tab1" class="tab">tab1</label>
    <label for="tab2" class="tab">tab2</label>
    <label for="tab3" class="tab">tab3</label>
  </div>
  <div class="downContainer">
    <input type="radio" name="tab" id="tab1" checked>
    <div class="content">content1</div>
    <input type="radio" name="tab" id="tab2">
    <div class="content">content2</div>
    <input type="radio" name="tab" id="tab3">
    <div class="content">content3</div>
  </div>
</div>
/* Hide .content by default. <input>s are also hidden. */
input, .content {
  display: none;
}

/* If one is checked, display the .content element next to them. */
input:checked + .content {
  display: block;
}

For further explanation, see this answer.

Try it:

input, .content {
  display: none;
}

input:checked + .content {
  display: block;
}


/* Demo only */

.container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100vh;
  align-items: center;
  justify-content: center;
}

.upContainer {
  display: flex;
}

.tab {
  width: 100px;
  height: 70px;
  background-color: aqua;
  cursor: pointer;
  text-align: center;
  margin: 0px 10px;
}

.content {
  width: 300px;
  height: 100px;
  margin-top: 10px;
  text-align: center;
  background-color: black;
  color: aliceblue;
}
<div class="container">
  <div class="upContainer">
    <label for="tab1" class="tab">tab1</label>
    <label for="tab2" class="tab">tab2</label>
    <label for="tab3" class="tab">tab3</label>
  </div>
  <div class="downContainer">
    <input type="radio" name="tab" id="tab1" checked>
    <div class="content">content1</div>
    <input type="radio" name="tab" id="tab2">
    <div class="content">content2</div>
    <input type="radio" name="tab" id="tab3">
    <div class="content">content3</div>
  </div>
</div>
InSync
  • 4,851
  • 4
  • 8
  • 30
0

Assuming that you mean you only want the content associated with a tab to be shown (and all the other tab content hidden) - you can iterate over the content elements and toggle the hidden class on/off depending on whether it matches a condition.

Using data attributes to store the ids rather than classes may make the process easier to code/understand.

// Cache the containers, and the contents
const tabContainer = document.querySelector('.tabContainer');
const contents = document.querySelectorAll('.content');

// Add a listener to the tab container
tabContainer.addEventListener("click", handleTab);

function handleTab(e) {

  // Check to see if the clicked element is a tab
  if (e.target.matches('.tab')) {
 
    // Grab the tab id from its dataset
    const { id: tabId } = e.target.dataset;

    // Toggle the contents on/off depending on whether
    // the content id equals the tab id
    contents.forEach(content => {
      const { id: contentId } = content.dataset;
      content.classList.toggle('hidden', contentId !== tabId)
    });
     
  }

}
.container,.tabContainer{display:flex}.content,.tab{text-align:center}.container{flex-direction:column;width:100%;height:100vh;align-items:center;justify-content:center}.tab{width:100px;height:70px;background-color:#0ff;cursor:pointer;margin:0 10px}.content{width:300px;height:100px;margin-top:10px;background-color:#000;color:#f0f8ff}.hidden{display:none}
<div class="container">
  <div class="tabContainer">
    <div data-id="1" class="tab">tab1</div>
    <div data-id="2" class="tab">tab2</div>
    <div data-id="3" class="tab">tab3</div>
  </div>
  <div class="contentContainer">
    <div data-id="1" class="content">content1</div>
    <div data-id="2" class="content hidden">content2</div>
    <div data-id="3" class="content hidden">content3</div>
  </div>
</div>

Additional documentation

Andy
  • 61,948
  • 13
  • 68
  • 95