Search code examples
javascriptcsspopup

Trying to close a popup image in Javascript


I am building an interface that displays 20 image elements in a list. When the user clicks on an image it should popup with details and with a button that should close it. This is how I am doing it:

for (let i = 0; i < 20; i++) {
    const div = document.createElement('div');
    div.innerHTML = `
    <div class = "card cursor">
      <div>
        <img
          src="/src/imgs/no-toy.jpeg"
          class="card-img-top"
        />
        </div>
        <div class="card-body">
            <h5 class="card-title">No toy shefilor</h5>
            <p class="card-text"> </p>
        </div>
    </div>
    <span class="close">&times;</span>  
    <div class="modal">
        <img class="modal-content" src="/src/imgs/no-toy.jpeg">
        <div id="caption"></div>
    </div>
    `;
    const modal = div.querySelector('.modal');
    const closeModal = div.querySelector('.close');
    div.addEventListener('click', () => {
        modal.style.display = 'block';
        closeModal.style.display = 'block';
    });
    closeModal.addEventListener('click', () => {
        modal.style.display = 'none';
        closeModal.style.display = 'none';
    });
    list.appendChild(div);
}

Before the user clicks, the close and modal classes are set as display: none in the CSS, style that changes when div receives an input. closeModal, which is the close button, has similar event listeners that change the styles back to 'none' yet clicking on it does nothing. I've tried logging the elements in the closeModal event but they stay with the same display that was given in the div event.


Solution

  • Based on the code you provided, the issue is occurring because the same element is being used both to trigger the modal and as the close button. When you click the close button, it also triggers the parent element, causing unexpected behavior.

    To resolve this issue, I suggest separating the open trigger from the close button. You can use a different element, such as an image, to trigger the opening of the modal. When the image element is clicked, you can add a CSS class, such as active, to the modal to show it. To close the modal, you can remove the active class from the modal.

    Here is an example code:

    for (let i = 0; i < 20; i++) {
        const div = document.createElement('div');
        div.innerHTML = `
        <div class = "card cursor" style="border: 1px solid green;">
          <div class="imageclick" style="border: 1px solid red;">
            <img
              src="/src/imgs/no-toy.jpeg"
              class="card-img-top"
            />
            </div>
            <div class="card-body">
                <h5 class="card-title">No toy shefilor</h5>
                <p class="card-text"> </p>
            </div>
        </div>
        <span class="close">&times;</span>  
        <div class="modal">
            <img class="modal-content" src="/src/imgs/no-toy.jpeg">
            <div id="caption"></div>
        </div>
        `;
        
        const modal = div.querySelector('.modal');
        const closeModal = div.querySelector('.close');
        const list = document.querySelector('.list');
        const img = div.querySelector('.imageclick');
        
        img.addEventListener('click', () => {
          
           modal.classList.add('active');
           
            // modal.style.display = 'block';
            // closeModal.style.display = 'block';
        });
        closeModal.addEventListener('click', () => {
            modal.classList.remove('active');
            
            // modal.style.display = 'none';
            // closeModal.style.display = 'none';
        });
        list.appendChild(div);
    }
    .modal {
      display: none;
    }
    
    .active {
      display: block;
    }
     <div class="list"></div> 

    I hope this explanation and example help you understand and address the issue you are facing.