0

Background

Referencing the MDN documentation on Popover API: https://developer.mozilla.org/en-US/docs/Web/API/Popover_API (not to be confused with Bootstrap's popover).

I have multiple popovers, something like this:

<div id="Popover_1" popover>Content of 1</div>
<div id="Popover_2" popover>Content of 2</div>

I'm attempting to trigger a function if a popover is toggled closed. I fully understand how to add an event listener to each popover and it works just fine. Something like:

window.onload = function() {
    const popovers = document.querySelectorAll("[popover]")
    popovers.forEach(popover => {
        popover.addEventListener("beforetoggle", (event) => {
            if (event.newState === "closed") {
                console.log(event);
            }
        });
    });
}

However, for the sake of simplicity, I'd like to use document.addEventListener instead, as I need to trigger the same function regardless of popover source. My understanding is that it should work due to the event bubbling up. I can't get it to. I recognize that some events do not, but in reviewing the MDN I don't see that it wouldn't.

Question

Therefore, my question is: Am I going about this wrong or is bubble up not working? Or, do I have a basic misunderstanding of what I'm dealing with?

1 Answer 1

2

No the event doesn't bubble, I'm not sure what made you think it does, but if you look at the specs, you can see that it's fired in here and here, and that in both cases its bubbles attribute is not set (only the cancelable one is set for the "open" case).

However, you can still capture that event for delegation:

document.addEventListener("click", (event) => {
  const btn = event.target.closest("button[data-target]");
  if (!btn) { return; }
  const { target } = btn.dataset;
  document.querySelector(`#Popover_${target}`).togglePopover();
});

document.addEventListener("beforetoggle", (event) => {
  const { newState, oldState, cancelable } = event;
  console.log({ newState, oldState });
}, { capture: true });
<button data-target=1>show 1</button>
<button data-target=2>show 2</button>
<div id="Popover_1" popover>Content of 1</div>
<div id="Popover_2" popover>Content of 2</div>

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

4 Comments

Thank you for pointing me to the whatwg.org links. I find MDN quite readable and a reliable resource for questions like this. When I was researching the question (which bootstrap made very hard to do) I noted that MDN usually calls out when an event does not bubble up. So because that was missing for popover, I wasn't sure the truth. I appreciate the additional insight, thank you!
Yes, MDN used to have tables that said so. It apparently got removed: github.com/mdn/content/issues/22198 According to that issue it should indeed be mentionned that the event doesn't bubble, but it's not and it's not the only case. I'll open an issue when I get time to get this sorted out, because it's indeed problematic. But I fear it won't be easy to fix, because of cases just like the beforetoggle one, where the same event can have different init options depending where it's been fired from (here the cancelable one).
Thank you for the extra effort, hopefully it's useful to others as well moving forward!

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.