javascripthtmlpopover

Popover API: How to stop the popover from closing


When using the popover API, I would like to, when light dismiss occurs, stop the popover from closing, and run custom js to remove the popover from the screen.

Is there a way to do this?

I tried to do this but this didn't work.

<style>
  div {
    height: 100px;
    width: 100px;
    background-color: hotpink;
  }
</style>
<div popover></div>
<script>
  document.querySelector("div").showPopover();
  document
    .querySelector("div")
    .addEventListener("beforetoggle", (event) => {
      if (event.newState === "closed") {
        event.preventDefault();
        event.stopPropagation();

        // Run custom JS to remove popover from dom 
      }
    });
</script>


Solution

  • Make the popover as a backdrop for an internal DIV acting as an actual popover. Then you can catch clicks and do anything you want, replace popover.hidePopover() to anything you want. If you want the backdrop transparent for mouse event you should some direct them manually, an example for click is provided:

    const popover = document.querySelector("[popover]");
    
    
    popover.showPopover(); popover.classList.toggle('opened');
    popover.addEventListener('beforetoggle', e => popover.classList.toggle('opened', e.newState !== 'closed'));
    popover.addEventListener("click", e => e.target.closest('.popover') || popover.hidePopover() || document.elementFromPoint(e.pageX, e.pageY)?.click());
    .popover{
        height: 150px;
        width: 150px;
        background-color: hotpink;
        box-shadow: 5px 5px 5px rgba(0,0,0,.3);
        border: 1px solid gray;
        border-radius: 5px;
      }
      .backdrop{
      border:none;
      width:100%;
      height:100%;
      background: transparent;
        }
        
        .opened{
          display:flex;
      align-items:center;
      justify-content:center;
      
      }
    <button onclick="console.log('button clicked')">Click me</button>
    <button onclick="$popover.showPopover()">Show popover</button>
    <div id="$popover" popover class="backdrop"><div class="popover"></div></div>