0

I have this piece of code below which is being used on a mobile navigation section of a website.

const toggleButton = document.querySelector(".header__nav-mobile .toggle");
const subMenu = document.querySelector(".header__nav-mobile .menu-item-has-children .sub-menu");

function toggleMenuItems() {
  if (toggleButton .classList.contains("open")) {
    toggleButton.classList.remove("open");
    subMenu.classList.remove("open");
  } else {
    toggleButton.classList.add("open");
    subMenu.classList.add("open");
  }
}

toggleButton.addEventListener("click", toggleMenuItems);

This works perfectly, but only for the very first item, so I am now using querySelectorAll below, but to no avail.

const toggleButton = document.querySelectorAll(".header__nav-mobile .toggle");
const subMenu = document.querySelectorAll(".header__nav-mobile .menu-item-has-children .sub-menu");

function toggleMenuItems() {
    for (let i = 0; i < toggleButton.length; i++) {
        if (toggleButton.classList.contains("open")) {
          toggleButton .classList.remove("open");
          subMenu.classList.remove("open");
        } else {
          toggleButton.classList.add("open");
          subMenu.classList.add("open");
        }
    }
}

toggleButton.addEventListener("click", toggleMenuItems);

Can someone point out where I'm going wrong please?

Johnny
  • 553
  • 1
  • 10
  • 27
  • you need to do something like this `toogleButton[i]` or easily use a `toogleButton.forEach((btn) => { /* paste your code here */ })` – Laaouatni Anas Mar 10 '23 at 15:45
  • 1
    Use `toggle` instead of `contains`/`remove`/`add`. Also, what @LaaouatniAnas said.. – Heretic Monkey Mar 10 '23 at 15:47
  • 1
    Does this answer your question? [What do querySelectorAll and getElementsBy\* methods return?](https://stackoverflow.com/questions/10693845/what-do-queryselectorall-and-getelementsby-methods-return) – Heretic Monkey Mar 10 '23 at 15:48

1 Answers1

0

When you run querySelector(), you get a DOM Element back which you can then add your event listener to, but when you run querySelectorAll(), you get a NodeList returned which you will need to iterate through to add event listeners to all the elements. You'll need to iterate through it like an array to add that event listener to all your toggleButtons.

const toggleButtons = document.querySelectorAll(".header__nav-mobile .toggle");

toggleButtons.forEach(button => {
  button.addEventListener("click", toggleMenuItems);
});

Now that said, you're going to need to modify your toggleMenuItems function a bit and make it more pure by passing in any elements you plan to toggle inside of it. I would pass the each toggleButton into the toggleMenuItems listener and then have it query for the proper subMenu for that specific toggleButton.

Depending on how you have your html written will dictate how you go about accessing the proper subMenu in your toggleMenuItems function.

Kyle Combs
  • 106
  • 1
  • 8