0

What I'm trying to do is link identical navbar ids and classes into a single event listener. This is for a blog that has different styling for different pages. Both ids/classes are the exact same, with similar names ( except some minor css changes ). Either set of ids/classes would work on their own ( menuNav or menuNav-c ). Copying, pasting the same code then changing the variables, functions and adding the "-c" at the ends didn't work either, naturally that is excessive code. Any help is appreciated.

let openCloseNav = document.querySelectorAll("#openCloseNav", "#openCloseNav-c");
let menuNav = document.querySelectorAll("#menuNav", "#menuNav-c");

openCloseNav.addEventListener("click", openCloseNavClick);

function openCloseNavClick() {
  openCloseNav.classList.toggle("toggle toggle-c");
  menuNav.classList.toggle("navOpen navOpen-c");
}

The console brings up "openCloseNav" is not a function. However if I remove either the first or second set of ids/classes, only one set will work.

EDIT

I got it working, thanks for the help folks. After more digging and tinkering, it all started to make more sense. For those who may have similar issues, here's what worked for me:

let firstMenuToggle = document.querySelectorAll("#openCloseNav");
let firstMenu = document.querySelectorAll("#menuNav");

for (let i = 0; i < firstMenuToggle.length; i++) {
  firstMenuToggle[i].addEventListener("click", function() {
    firstMenuToggle[i].classList.toggle("toggle");
    firstMenu[i].classList.toggle("navOpen");
  });
}

let secondMenuToggle = document.querySelectorAll("#openCloseNav-c");
let secondMenu = document.querySelectorAll("#menuNav-c");

for (let i = 0; i < secondMenuToggle.length; i++) {
  secondMenuToggle[i].addEventListener("click", function() {
    secondMenuToggle[i].classList.toggle("toggle-c");
    secondMenu[i].classList.toggle("navOpen-c");
  });
}
thx1138
  • 110
  • 8
  • 2
    querySelectorAll returns a node list, you need to loop over the items on that list and call addEventListener for each one of them individually … – 04FS Feb 27 '19 at 10:58
  • As mentioned above the result is in a `NodeList`. This resource shows you an example on the return value and how to access the matched elements **[here](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll)** - Hope it helps :) – Nope Feb 27 '19 at 11:03

1 Answers1

0

querySelectorAll returns a list of the document's elements that match the specified group of selectors.

Please check the documentation here : MDN querySelectorAll

To add event listeners to all you should use :

openCloseNav.forEach((x) => { x.addEventListener("click", openCloseNavClick)} );

This will attach event listeners to all the matched document's elements in openCloseNav.

  • `openCloseNav` is a `NodeList`, which does not have a `forEach` prototype. You need to either use call: `[].forEach.call(openCloseNave, (x) => {});` or spread the `Iterable` first: `[...openCloseNav].forEach((x) => {});` – briosheje Feb 27 '19 at 11:30
  • @briosheje - MDN clearly says `Although NodeList is not an Array, it is possible to iterate over it with forEach()` [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList) [NodeList/forEach](https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach) Please check the links. – trideep_chatterjee Feb 28 '19 at 05:36