1

I have been making an advent calendar and want all doors to open on click. I have the animation down and it works, but only if I use querySelector; querySelectorAll doesn't seem to work. I've made three doors to test on and have yet to get them to all animate, as well as for the background to show for all of them (but that is a different topic). I feel like the problem is somewhere in the way I've written the HTML, since the JS has worked previously. I am fairly new at this and am hoping to do a calendar without utilizing grid or referencing others code.

Code Below

HTML

<div class="door-back">
  <button class="door d25">25</button>
  <button class="door d24">24</button>
  <button class="door d23">23</button>
</div>

CSS (including the random positions I've made for the door locations)

.door-back {
  position: relative;
  height: 50px;
  width: 50px;
  border-radius: 50px;
  background: hotpink;
  margin: 50px;
}

.door {
  position: absolute;
  height: 50px;
  width: 50px;
  color: white;
  border: 2px solid teal;
  border-radius: 50px;
  background: indianred;
  cursor: pointer;
  transform-origin: left;
  transition: all 0.5s ease-in-out;
}

.d25 {
  top: 100px;
  bottom: 100px;
  left: 590px;
  right: 5px;
}
.d24 {
  top: 300px;
  bottom: 500px;
  left: 390px;
  right: 50px;
}
.d23 {
  top: 500px;
  bottom: 100px;
  left: 800px;
  right: 600px;
}
.doorOpen {
  transform: perspective(1200px) translateZ(0px) translateX(0px) translateY(0px) rotateY(-150deg);
}

JavaScript

const door = document.querySelectorAll('.door')
door.addEventListener('click', toggleDoor)

function toggleDoor() {
  door.classList.toggle('doorOpen')
}

Like I said above, querySelector('.door') works, but only for d25 as it's the first element of its kind. Door I need to make it an array? Perhaps I should be doing querySelectorAll("button")?

Any help and/or advice would be greatly appreciated! Thank you and hope you're staying safe out there!

LovelyAndy
  • 841
  • 8
  • 22

1 Answers1

-1

querySelectorAll returns a NodeList, not an element. So you can't add event listener to it directly.

function toggleDoor(event) {
  event.target.classList.toggle('doorOpen')
}


let doors = document.querySelectorAll('.door');
[...doors].forEach(door => {
  door.addEventListener('click', toggleDoor)
})

querySelector works because it returns the first matched element.

Bulent
  • 3,307
  • 1
  • 14
  • 22
  • Thank you for the comment! The code snippet you've entered doesn't seem to work either. I'm getting 4 problems for vscode. I think one of them is [...doors].forEach isn't the right syntax? Any ideas why that may be? – LovelyAndy Oct 21 '20 at 20:10
  • It's the right syntax. Please tell me about the error message you get. The line inside forEach can be incorrect, but I copy that line directly from your code. – Bulent Oct 21 '20 at 20:41
  • It just gives me red lines under the " ... " the closing bracket and period " ]. " and then the open parens after forEach(. and gives a 4 next to the title saying "4 problems in this file". Thanks again for commenting back! If I could get this working on all 25 buttons that would be amazing! – LovelyAndy Oct 21 '20 at 20:45
  • Your function was incorrect. See my answer for the fixed version. – Bulent Oct 21 '20 at 20:49