How to target ::backdrop in Javascript to close modal?

203 views Asked by At

I have a modal popup using the dialog element which creates a backdrop pseudo element. i want people to be able to click anywhere that causes the modal to close. However i can't quite target the element to close it out. Below is what i tried. It gives me an error saying it can't read the properties of the event listener. anyone have an idea how to target this pseudo element?

   const openModalButton = document.querySelector(".open-modal");
        const modal = document.querySelector(".video-modal");
        const backdrop = document.querySelector("dialog:-internal-dialog-in-top-layer::backdrop");
        const video = document.querySelector(".video-modal video");

        openModalButton.addEventListener("click", function onOpen() {
          modal.showModal();
          //if we want autoplay, disable comment below
          //video.play();
        });

        modal.addEventListener("close", function onClose() {
          video.pause();
        });
        backdrop.addEventListener("close", function onClose() {
          video.pause();
        });
#retirement-services dialog.video-modal {
  border: none;
  padding: 40px;
  border-radius: 21px;
  transition: all 0.2s ease-in-out;
}
#retirement-services .video-modal-close {
  border: none;
  position: absolute;
  right: 16px;
  top: 16px;
  cursor: pointer;
  height: 25px;
  width: 25px;
  background-color: #e5e1de;
  border-radius: 50%;
  display: inline-block;
}
#retirement-services .open-modal {
  cursor: pointer;
}
    <div class="col open-modal">
              <div class="play-button open-modal" style="position: absolute">
              click me
              </div>
             
              <dialog class="video-modal">
                <form method="dialog">
                  <button class="video-modal-close">X</button>
                </form>
                <video controls width="220">
                  <source
                    src="https://www.w3schools.com/html/mov_bbb.mp4"
                    type="video/mp4"
                  />
                </video>
              </dialog>
            </div>

2

There are 2 answers

0
SyndRain On

You cannot assign events to pseudo-elements. However, an click event will be triggered even when the dialog's backdrop background is clicked, so you can make use of the click event on the modal instead.

In the handler, use e.target === e.currentTarget to check that the event is not bubbled up by the child elements of the modal.

const openModalButton = document.querySelector(".open-modal");
const modal = document.querySelector(".video-modal");
const video = document.querySelector(".video-modal video");

openModalButton.addEventListener("click", function onOpen() {
  modal.showModal();
});

modal.addEventListener("close", function onClose() {
  video.pause();
});

document.querySelector(".video-modal").addEventListener('click', function(e) {
  if (e.target === e.currentTarget) {
    e.stopPropagation();
    modal.close();
  }
})
#retirement-services dialog.video-modal {
  border: none;
  padding: 40px;
  border-radius: 21px;
  transition: all 0.2s ease-in-out;
}

#retirement-services .video-modal-close {
  border: none;
  position: absolute;
  right: 16px;
  top: 16px;
  cursor: pointer;
  height: 25px;
  width: 25px;
  background-color: #e5e1de;
  border-radius: 50%;
  display: inline-block;
}

#retirement-services .open-modal {
  cursor: pointer;
}
<div class="col open-modal">
  <div class="play-button open-modal" style="position: absolute">
    click me
  </div>

  <dialog class="video-modal">
    <form method="dialog">
      <button class="video-modal-close">X</button>
    </form>
    <video controls width="220">
        <source
          src="https://www.w3schools.com/html/mov_bbb.mp4"
          type="video/mp4"
        />
      </video>
  </dialog>
</div>

0
Marcel Maier On

i think it is not possible to bind an eventlistener to a pseudo element. instead you can add a eventlistener to document and check if the click happens outside of your dialog by using the event composedpath method.

https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath