Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Last iteration(?) of a NodeList causing Uncaught TypeError

The code works just as expected but if I use for (let line in hamburgerLines) {...} I get the following error: "Uncaught TypeError: Cannot read properties of undefined (reading ‘toggle’) at HTMLDivElement.addClass".

I used this alert function alert("Here: " + line + " "+ hamburgerLines[line] + " " + hamburgerLines.length); to find out what’s happening. It iterates normally three times and hamburgerLines.length does return 3 but then pops up another time putting out: "Here: entries function entries() { [native code] } 3" which I assume causes the error.

I already fixed this by changing it to for (let line = 0; line < hamburgerLines.length; line++) {...} but would like to know why it iterates once more through the for loop.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

let hamburgerButton = document.getElementById('hamburger-button');
hamburgerButton.addEventListener('click', addClass);

function addClass() {
  let hamburgerLines = document.querySelectorAll('.hamburger-line');
  for (let line in hamburgerLines) {
    hamburgerLines[line].classList.toggle('open-test');
  }
}
header #hamburger-button {
  position: absolute;
  width: 50px;
  height: 40px;
  top: 30px;
  right: 50px;
  cursor: pointer;
}


/* ---- Untoggled Hamburger Button ---- */

header .hamburger-line:nth-child(1) {
  width: 1px;
  height: 30px;
  background-color: #000;
  position: absolute;
  right: 0px;
  -webkit-transition: .5s ease-in-out;
}

header .hamburger-line:nth-child(2) {
  width: 1px;
  height: 20px;
  background-color: #000;
  position: absolute;
  right: 10px;
  -webkit-transition: .5s ease-in-out;
}

header .hamburger-line:nth-child(3) {
  width: 1px;
  height: 14px;
  background-color: #000;
  position: absolute;
  right: 20px;
  -webkit-transition: .5s ease-in-out;
}


/* ---- Toggled Hamburger Button ---- */

header .hamburger-line.open-test:nth-child(1) {
  width: 1px;
  height: 30px;
  background-color: #F00;
  position: absolute;
  right: 10px;
  -webkit-transition: .5s ease-in-out;
  transform: rotate(45deg);
}

header .hamburger-line.open-test:nth-child(2) {
  width: 1px;
  height: 20px;
  background-color: #FFF;
  position: absolute;
  transform: translateY(20px);
  -webkit-transition: .5s ease-in-out;
  opacity: 0;
}

header .hamburger-line.open-test:nth-child(3) {
  width: 1px;
  height: 30px;
  background-color: #F00;
  position: absolute;
  right: 10px;
  -webkit-transition: .5s ease-in-out;
  transform: rotate(-45deg);
}
<header>
  <div id="hamburger-button">
    <span class="hamburger-line"></span>
    <span class="hamburger-line"></span>
    <span class="hamburger-line"></span>
  </div>
</header>

>Solution :

document.querySelectorAll() returns a NodeList object, check NodeList documentation

Don’t use for…in to enumerate the items in NodeLists, since they
will also enumerate its length and item properties and cause errors if
your script assumes it only has to deal with element objects. Also,
for..in is not guaranteed to visit the properties in any particular
order.

for…of loops will loop over NodeList objects correctly:

Recent browsers also support iterator methods (forEach()) as well as
entries(), values(), and keys().

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading