2

The MDN docs say that the visibilitychange event

fires with a visibilityState of hidden when a user navigates to a new page, switches tabs, closes the tab, minimizes or closes the browser, or, on mobile, switches from the browser to a different app.

While I recall having experience with this being true, it looks like it isn't anymore (at least not on either Chrome or Firefox). I'm currently on desktop Chrome Version 121.0.6167.160

To reproduce, if I look at the end-of-session analytics example and basically copy-paste the function into the browser console like

document.onvisibilitychange = () => {
  console.log(document.visibilityState);
};

then I'll see "hidden" and "visible" logged to the console as I switch between open tabs. However, if I then click a random link that takes me to another page, nothing is logged and so I'm left to assume that the visibilitychange event is not firing in this case (the preserve-log option is checked in the dev console).

And just as an ultra-sanity check, the same behavior happens if I replace the console log with an actual sendbeacon request.

It sounds unlikely that a browser bug was pushed since it's happening in both chrome and firefox, so what am I missing / not understanding here?

8
  • I just reproduced this.
    – Barmar
    Commented Feb 14 at 0:31
  • @JaromandaX the beforeunload event has problems -- it's not reliably fired on mobile and also apparently isn't compatible with the bfcache on firefox according to mdn
    – jdrub
    Commented Feb 14 at 1:02
  • @JaromandaX what browser / version? do you have a specific publicly-accessible page? And what exactly do you mean that it works? You’re seeing “hidden” as you navigate away?
    – jdrub
    Commented Feb 14 at 3:19
  • @JaromandaX by just following my repro instructions on this very page and clicking the mdn link in the original post, I am able to repro on the version of chrome that I listed. What actual version of firefox are you using?
    – jdrub
    Commented Feb 14 at 4:46
  • For me on Firefox from the same page, the console is acting weird (with persist logs on): the message won't print to it until the page is revived through history navigation. However the message will print at the correct position (i.e. before the "Navigated to" message) when it does print... Trying another script to be sure, the event fires as expected though: onclick=e=>{ onclick = null; const win=open("./"); document.onvisibilitychange=()=>win.document.body.textContent=document.visibilityState; } Basically we open a popup window on click and then write to it in the event.
    – Kaiido
    Commented Feb 14 at 5:34

1 Answer 1

2

No it still fires, you must have messed up with your tests.

This is being tested in web-tests which are ran as part of the update workflow of every browser, at every code change, so you can be sure that it won't stop working.

Note that using the console may be unreliable because the page that controls the console is unloaded and thus may not be able to communicate with the console in time. Instead prefer using a popup window as a "console" and write to that popup from your main page in the visibilitychange event. This way, even when the main page is navigated away, the popup state is preserved and you can see if it received the changes set from the event or not. The web-test actually does the inverse, opening a popup and listening for the event in it instead, but the gist is the same.

Not the answer you're looking for? Browse other questions tagged or ask your own question.