2

I am creating a dropdown menu that contains three submenus. My challenge right now is being able to open each submenu when I click on an arrow image next to the parent LI. At the moment with my current script, it is only affecting the first parent LI, opening its respective submenu. Yet the other two submenus are not being targeted.

const arrowButton = document.querySelectorAll(".menu-arrow");
const subMenu = document.querySelector(".sub-menu");

arrowButton.forEach((el) =>
  el.addEventListener("click", () => {
    subMenu.classList.toggle("open");
  })
);
.sub-menu {
  display: none;
}

.sub-menu.open {
  display: flex;
  flex-direction: column;
  background-color: $footer-text;
  width: 60vw;
  margin: 0 auto;
  color: $darkblue-headingtext;
  border-radius: 5px;
}
<ul class="nav__links">
  <li class="parent">
    Product
    <img class="menu-arrow" src="./images/icon-arrow-dark.svg" alt="arrow" />
    <ul class="sub-menu">
      <li>Overview</li>
      <li>Pricing</li>
      <li>Marketplace</li>
      <li>Features</li>
      <li>Integrations</li>
    </ul>
  </li>
  <li class="parent">
    Company
    <img class="menu-arrow" src="./images/icon-arrow-dark.svg" alt="arrow" />
    <ul class="sub-menu">
      <li>About</li>
      <li>Team</li>
      <li>Blog</li>
      <li>Careers</li>
    </ul>
  </li>
  <li class="parent">
    Connect
    <img class="menu-arrow" src="./images/icon-arrow-dark.svg" alt="arrow" />
    <ul class="sub-menu">
      <li>Contact</li>
      <li>Newsletter</li>
      <li>LinkedIn</li>
    </ul>
  </li>
</ul>

Preview of what Im building

I would greatly appreciate any tips! Thank you!!

3 Answers 3

3

The problem is that you use querySelector which selects only the first found element. But you can use the event itself which is provided through every event listener and get the clicked target with event.target. Then you could simply select the next element with nextElementSibling but perhaps the position of the submenu changes during the development process, so it would be better to select the parent of that target with .parentElement and select the submenu class like you did above with .querySelector(".sub-menu").

Working example:

const arrowButton = document.querySelectorAll(".menu-arrow");

arrowButton.forEach((el) =>
  el.addEventListener("click", (event) => {
    const subMenu = event.target.parentElement.querySelector(".sub-menu");
    subMenu.classList.toggle("open");
  })
);
.sub-menu {
  display: none;
}

.sub-menu.open {
  display: flex;
  flex-direction: column;
  background-color: $footer-text;
  width: 60vw;
  margin: 0 auto;
  color: $darkblue-headingtext;
  border-radius: 5px;
}
<ul class="nav__links">
  <li class="parent">
    Product
    <img class="menu-arrow" src="./images/icon-arrow-dark.svg" alt="arrow" />
    <ul class="sub-menu">
      <li>Overview</li>
      <li>Pricing</li>
      <li>Marketplace</li>
      <li>Features</li>
      <li>Integrations</li>
    </ul>
  </li>
  <li class="parent">
    Company
    <img class="menu-arrow" src="./images/icon-arrow-dark.svg" alt="arrow" />
    <ul class="sub-menu">
      <li>About</li>
      <li>Team</li>
      <li>Blog</li>
      <li>Careers</li>
    </ul>
  </li>
  <li class="parent">
    Connect
    <img class="menu-arrow" src="./images/icon-arrow-dark.svg" alt="arrow" />
    <ul class="sub-menu">
      <li>Contact</li>
      <li>Newsletter</li>
      <li>LinkedIn</li>
    </ul>
  </li>
</ul>

Sign up to request clarification or add additional context in comments.

2 Comments

Biberman, I greatly appreciate your feedback. I learned through your post about .parentElement. Thank you.. thank you..
If that answers your question you should mark it as accepted (see stackoverflow.com/help/someone-answers).
2

With this line const subMenu = document.querySelector(".sub-menu"); you will get always the first element, that is why the first menu is opened not matter what node was clicked. You need to get the submenu node next to the clicked element:

arrowButton.forEach((el) =>
  el.addEventListener("click", () => {
    const subMenu = el.parentNode.querySelector(".sub-menu");
    subMenu.classList.toggle("open");
  })
);

Comments

1
const arrowButton = document.querySelectorAll(".menu-arrow");

arrowButton.forEach((el) =>
  el.addEventListener("click", (e) => {
    e.target.nextElementSibling.classList.toggle("open");
  })
);

1 Comment

you're welcome my friend. please accept my answer and vote me <3 .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.