skip to Main Content

I’m relatively new to JS, I’m working on my personal project.

So there is a div container, inside the div container there is n number of sub-containers, which all have a button, and another div which is the content. I want each button of the sub-container to open and close the content when clicked. There can be as many sub-containers as possible, but each button of the sub-container should only be able to open/close its respective content.

For the sake of simplicity, I haven’t put the actual code of my project, because it includes a lot of unimportant icons and design elements, I think the example below can explain my problem.

I only put two sub-containers, but we should be able to add as many as possible.

In my own code, the first sub-container works perfectly, it opens and closes as expected, but by clicking on the second or third or the nth sub-container, it just opens and closes the first one’s content, not its respective one. I hope I’ve explained it clearly. Any help would be appreciated. Thanks.

function openContent() {
  let partContainer = document.querySelectorAll(".container");

  partContainer.forEach((parent) => {
    let part = parent.querySelector(".thisPart");
    let content = parent.querySelector(".content");

    if (content.style.display === "none") {
      content.style.display = "flex";
    } else {
      content.style.display = "none";
    }
  });
}
<div class="container">
  <div class="subContainer">
    <button class="thisPart" onclick="openContent()">Open Content 1</button>
    <div class="content">Content 1</div>
  </div>
  <div class="subContainer">
    <button class="thisPart" onclick="openContent()">Open Content 1</button>
    <div class="content">Content 1</div>
  </div>
</div>

2

Answers


  1. You need to delegate instead of using queySelectorAll

    I wrapped containers in a div with id="containers"

    document.getElementById("containers").addEventListener("click", (e) => {
      const tgt = e.target.closest(".thisPart"); // in case there are icons and stuff
      if (!tgt) return; // not a button
      const content = tgt.nextElementSibling;
      content.hidden = !content.hidden;
    })  
    <div id="containers">
      <div class="container">
        <div class="subContainer">
          <button class="thisPart">Open Content 1</button>
          <div class="content" hidden>Content 1</div>
        </div>
        <div class="subContainer">
          <button class="thisPart">Open Content 2</button>
          <div class="content" hidden>Content 2</div>
        </div>
      </div>
      <div class="container">
        <div class="subContainer">
          <button class="thisPart">Open Content 1</button>
          <div class="content" hidden>Content 1</div>
        </div>
        <div class="subContainer">
          <button class="thisPart">Open Content 2</button>
          <div class="content" hidden>Content 2</div>
        </div>
      </div>
    </div>
    Login or Signup to reply.
  2. I this you should use .toggle property
    Check out
    your javascript file

    
    function openContent() {
        let partContainer = document.querySelectorAll(".container");
    
        partContainer.forEach((parent) => {
            parent.classList.toggle("hidden");
    }
    
    

    Now create a class in your css file

    .hidden {
    display: hidden;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search