0

I have a problem with the for-each loop on a practice page.

There are 4 different popups on my page and all of them got a close button. So i wrote this lines four times into my html-code:

<div class="description-modal dm-1">
<i class="fa-solid fa-xmark close-m" id="close-m-1"></i>
<h3>Test</h3>
</div>

To activate them I gave them ID's from 1 to 4 and added the class "active" on click. To close them I tried to use this foreach loop:

const modals_all = document.querySelectorAll('.description-modal');
const close_buttons = document.querySelectorAll('.close-m')


modals_all.forEach(modal =>{
  close_buttons.forEach(close_button =>{
    close_button.addEventListener('click', ()=>{
      if (modal.classList.contains('active')){
        modal.classList.remove('active')
      } else {
        return
      }
    })
  })
});

Unfortunatly it doesn't work and i have no idea why, cause the console doesn't show an error. What's the right way to solve this?

1
  • And no need for loops at all with event delegation. Commented Jul 26, 2022 at 13:36

2 Answers 2

2

You want to match between the button and the modal it belongs. This is done by selecting the button that's inside it.

const modals_all = document.querySelectorAll('.description-modal');
// const close_buttons = document.querySelectorAll('.close-m')

modals_all.forEach(modal => {
  var close_button = modal.querySelector('.close-m')
  close_button.addEventListener('click', () => {
    if (modal.classList.contains('active')) {
      modal.classList.remove('active')
    } else {
      return
    }
  })
});
.description-modal {
  border: 1px solid black;
  padding: 10px;
  margin: 10px;
}

.description-modal.active {
  background: lightgray;
}
<div class="description-modal active dm-1">
  <i class="fa-solid fa-xmark close-m" id="close-m-1">close</i> &larr;click
  <h3>Test</h3>
</div>

<div class="description-modal active dm-1">
  <i class="fa-solid fa-xmark close-m" id="close-m-2">close</i> &larr;click
  <h3>Test</h3>
</div>

<div class="description-modal active dm-1">
  <i class="fa-solid fa-xmark close-m" id="close-m-3">close</i> &larr;click
  <h3>Test</h3>
</div>

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

2 Comments

Just read this after writing my answer, I entirely agree with this post! No need for nested loops for this.
Dennibl, if it worked you can accept his answer as correct so if other people find this page with the same issue they can see where to find the solution :)
0

I do not think you need nested loops to do this. Just one loop on the modals should suffice? I would just loop the modals and get the close button as a child element of the modal.

I have not tested this code but I think something similar to this should help you out:

const modals_all = document.querySelectorAll('.description-modal');

modals_all.forEach(modal =>{
  let closeBtn = modal.querySelector('.close-m');

  closeBtn.addEventListener('click', (e) => {
    if(modal.classList.contains('active') || modal.style.display === 'block'){
      modal.classList.remove('active');
      //modal.style.display = 'none';
    };
  });

});

Just make sure the CSS is also doing what you expect too, otherwise adding and removing classes will not do what you expect. I hope this helps.

Comments

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.