skip to Main Content

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>

3

Answers


  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>
    Login or Signup to reply.
  2. 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>
    Login or Signup to reply.
  3. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search