javascripthtmlcssmodal-dialog

Close Modal when clicked on other div


I want to have it work like so: If you click on one paw the modal opens and if you click on the second paw the modal of paw 1 closes. What do i have to add to the script to make it work? Right now the modal opens in the background of the current active modal.

//Start Modal One
const openModalButtonOne = document.querySelectorAll('[data-modal-target]')
const closeModalButtonOne = document.querySelectorAll('[data-close-button]')
const overlayOne = document.getElementById('overlay')

openModalButtonOne.forEach(button => {
  button.addEventListener('click', () => {
    const info1 = document.querySelector(button.dataset.modalTarget)
    openModal(info1)
  })
})

overlayOne.addEventListener('click', () => {
  const info1 = document.querySelectorAll('.infobox.active')
  info1.forEach(info1 => {
    closeModal(info1)
  })
})

closeModalButtonOne.forEach(button => {
  button.addEventListener('click', () => {
    const info1 = button.closest('.infobox')
    closeModal(info1)
  })
})

function openModal(info1) {
  if (info1 == null) return
  info1.classList.add('active')
  overlayOne.classList.add('active')
}

function closeModal(info1) {
  if (info1 == null) return
  info1.classList.remove('active')
  overlayOne.classList.remove('active')
}

//Start Modal Two
const openModalButtonTwo = document.querySelectorAll('[data-modal-target]')
const closeModalButtonTwo = document.querySelectorAll('[data-close-button]')
const overlayTwo = document.getElementById('overlay')

openModalButtonTwo.forEach(button => {
  button.addEventListener('click', () => {
    const info2 = document.querySelector(button.dataset.modalTarget)
    openModal(info2)
  })
})

overlayTwo.addEventListener('click', () => {
  const info2 = document.querySelectorAll('.infobox.active')
  info2.forEach(info2 => {
    closeModal(info2)
  })
})

closeModalButtonTwo.forEach(button => {
  button.addEventListener('click', () => {
    const info2 = button.closest('.infobox')
    closeModal(info2)
  })
})

function openModal(info2) {
  if (info2 == null) return
  info2.classList.add('active')
  overlayTwo.classList.add('active')
}

function closeModal(info2) {
  if (info2 == null) return
  info2.classList.remove('active')
  overlayTwo.classList.remove('active')
}
.infobox {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0);
  transition: 200ms ease-in-out;
  z-index: 200;
  background-color: #D0D0CE;
  width: 500px;
  max-width: 80%;
}

.infobox.active {
  transform: translate(-50%, -50%) scale(1);
}

#overlay {
  position: fixed;
  opacity: 0;
  transition: 200ms ease-in-out;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, .7);
  pointer-events: none;
}

#overlay.active {
  opacity: 1;
  pointer-events: all;
}

.title {
  padding: 0 10px 0 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.close-button {
  cursor: pointer;
  border: none;
  outline: none;
  background: none;
  font-size: 1.25rem;
  font-weight: bold;
}

.infoheadline {
  text-transform: uppercase;
  font-family: 'Roboto Condensed', sans-serif;
  padding-left: 5px;
}

.infotext {
  padding: 10px 15px;
  font-family: 'Roboto', sans-serif;
}

.linesmall {
  width: 20%;
  height: 5px;
  margin-left: 10px;
  background-color: #FABB00;
}

.paw {
  width: 42px;
  height: 42px;
  padding: 16px;
  z-index: 1;
  filter: drop-shadow(0px 0px 5px #ffffff);
}
<!--Pfote 1 Start-->
<div class="item one">
  <div id="overlay"></div>
  <input type="image" data-modal-target="#info1" src="https://media.visioneleven.com/JW/116_Nachhaltigkeit_Wiesen/image_assets/paw.png" alt="Pfote" class="paw">
  <div id="info1" class="infobox eins">
    <div class="title">
      <h3 class="infoheadline">3.500 mal tierischer</h3>
      <button data-close-button class="close-button">&times;</button>
    </div>
    <div class="linesmall"></div>
    <p class="infotext">Wiesen bieten Lebensraum für rund 3.500 Tierarten – z. B. Vögel, Käfer, Spinnen, Heuschrecken, Schmetterlinge, Bienen, Hummeln ...</p>
  </div>
</div>
<!--Pfote 1 Ende-->

<!--Pfote 2 Start-->
<div class="item two">
  <div id="overlay"></div>
  <input type="image" data-modal-target="#info2" src="https://media.visioneleven.com/JW/116_Nachhaltigkeit_Wiesen/image_assets/paw.png" alt="Pfote" class="paw">
  <div id="info2" class="infobox zwei">
    <div class="title">
      <h3 class="infoheadline">588 Mrd. mal klimafreundlicher</h3>
      <button data-close-button class="close-button">&times;</button>
    </div>
    <div class="linesmall"></div>
    <p class="infotext">Allein in Deutschland speichern Wiesen ca. 588 Milliarden Tonnen CO<sub>2</sub> – und entziehen sie damit der Atmosphäre. (Zum Vergleich: Unsere Wälder speichern ca. 372 Mrd. t).</p>
  </div>
</div>
<!--Pfote 2 Ende-->


Solution

  • I think you tried to overcomplicate the stuff. Here's a modified version of your code that behaves as expected:

    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style type="text/css">
          .infobox {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%) scale(0);
            transition: 200ms ease-in-out;
            z-index: 200;
            background-color: #d0d0ce;
            width: 500px;
            max-width: 80%;
          }
    
          .infobox.active {
            transform: translate(-50%, -50%) scale(1);
          }
    
          #overlay {
            position: fixed;
            opacity: 0;
            transition: 200ms ease-in-out;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(0, 0, 0, 0.7);
            pointer-events: none;
          }
    
          #overlay.active {
            opacity: 1;
            pointer-events: all;
          }
    
          .title {
            padding: 0 10px 0 0;
            display: flex;
            justify-content: space-between;
            align-items: center;
          }
    
          .close-button {
            cursor: pointer;
            border: none;
            outline: none;
            background: none;
            font-size: 1.25rem;
            font-weight: bold;
          }
    
          .infoheadline {
            text-transform: uppercase;
            font-family: "Roboto Condensed", sans-serif;
            padding-left: 5px;
          }
    
          .infotext {
            padding: 10px 15px;
            font-family: "Roboto", sans-serif;
          }
    
          .linesmall {
            width: 20%;
            height: 5px;
            margin-left: 10px;
            background-color: #fabb00;
          }
    
          .paw {
            width: 42px;
            height: 42px;
            padding: 16px;
            z-index: 1;
            filter: drop-shadow(0px 0px 5px #ffffff);
          }
        </style>
      </head>
      <body>
        <div id="overlay"></div>
    
        <!--Pfote 1 Start-->
        <div class="item one">
          <input
            type="image"
            data-modal-target="#info1"
            src="https://media.visioneleven.com/JW/116_Nachhaltigkeit_Wiesen/image_assets/paw.png"
            alt="Pfote"
            class="paw"
          />
          <div id="info1" class="infobox eins">
            <div class="title">
              <h3 class="infoheadline">3.500 mal tierischer</h3>
              <button data-close-button class="close-button">&times;</button>
            </div>
            <div class="linesmall"></div>
            <p class="infotext">
              Wiesen bieten Lebensraum für rund 3.500 Tierarten – z. B. Vögel,
              Käfer, Spinnen, Heuschrecken, Schmetterlinge, Bienen, Hummeln ...
            </p>
          </div>
        </div>
        <!--Pfote 1 Ende-->
    
        <!--Pfote 2 Start-->
        <div class="item two">
          <input
            type="image"
            data-modal-target="#info2"
            src="https://media.visioneleven.com/JW/116_Nachhaltigkeit_Wiesen/image_assets/paw.png"
            alt="Pfote"
            class="paw"
          />
          <div id="info2" class="infobox zwei">
            <div class="title">
              <h3 class="infoheadline">588 Mrd. mal klimafreundlicher</h3>
              <button data-close-button class="close-button">&times;</button>
            </div>
            <div class="linesmall"></div>
            <p class="infotext">
              Allein in Deutschland speichern Wiesen ca. 588 Milliarden Tonnen
              CO<sub>2</sub> – und entziehen sie damit der Atmosphäre. (Zum
              Vergleich: Unsere Wälder speichern ca. 372 Mrd. t).
            </p>
          </div>
        </div>
        <!--Pfote 2 Ende-->
    
        <script type="text/javascript">
          //Start Modal One
          const openModalButtons = document.querySelectorAll("[data-modal-target]");
          const closeModalButtons = document.querySelectorAll(
            "[data-close-button]"
          );
          const overlay = document.querySelector("#overlay");
    
          const closeActiveModals = () => {
            const info = document.querySelectorAll(".infobox.active");
            info.forEach((info) => {
              closeModal(info);
            });
          };
    
          openModalButtons.forEach((button) => {
            button.addEventListener("click", () => {
              closeActiveModals();
              const info = document.querySelector(button.dataset.modalTarget);
              openModal(info);
            });
          });
    
          overlay.addEventListener("click", closeActiveModals);
    
          closeModalButtons.forEach((button) => {
            button.addEventListener("click", () => {
              const info = button.closest(".infobox");
              closeModal(info);
            });
          });
    
          function openModal(info) {
            if (info == null) return;
            info.classList.add("active");
            overlay.classList.add("active");
          }
    
          function closeModal(info) {
            if (info == null) return;
            info.classList.remove("active");
            overlay.classList.remove("active");
          }
        </script>
      </body>
    </html>
    

    Note that you don't need to add event listeners twice as you're querying the DOM with querySelectorAll and then iterating through them to add event listeners. Also, for the same exact reason, you don't need to add all of the functions such as openModal twice neither.

    Just don't try to make it complicated. It's very simple.