DEV Community

DEV Community

Google Web Dev profile image

Posted on Sep 17, 2018 • Updated on May 2, 2019

Sure you want to leave?ā€”browser beforeunload event

In the video, I explain a bit about the beforeunload eventā€”which lets you prompt or warn your user that they're about to leave your page. If misused, this can be frustrating for your usersā€”why would you use it? šŸ’ā€ā™‚ļøā„¹ļø

āœ… Your user is part way through completing a form, e.g., a purchase āœ… There's a network POST that's in-flight, e.g., saving a preference āœ… Your user is writing a blog post or a comment and it'll be lost šŸ¤· A video or music will stop playing ā›” Your user hasn't finished reading an article ā›” There's an unread email inside an email client ā›” There's a Time Sensitive Offer! Buy Now! šŸ™„šŸ’ø

Important To Remember

Before we get into the code, what is the tl;dr from my video? šŸ“ŗšŸ‘Øā€šŸ«

  • use the beforeunload event to warn a user they're going to close your page, but only when it's important
  • a Set of Promise objects can be useful to control beforeunload
  • ā€¦ and, maybe you can use sendBeacon rather than prompting at all!

If you'd like to learn more, read on! ā¬‡ļøšŸ“–

Unload Basics

If you want to prompt or warn your user that they're going to close your page, you need to add code that sets .returnValue on a beforeunload event:

There's two things to remember.

Most modern browsers (Chrome 51+, Safari 9.1+ etc) will ignore what you say and just present a generic message. This prevents webpage authors from writing egregious messages, e.g., "Closing this tab will make your computer EXPLODE! šŸ’£".

Showing a prompt isn't guaranteed. Just like playing audio on the web , browsers can ignore your request if a user hasn't interacted with your page. As a user, imagine opening and closing a tab that you never switch toā€”the background tab should not be able to prompt you that it's closing.

Optionally Show

You can add a simple condition to control whether to prompt your user by checking something within the event handler. This is fairly basic good practice, and could work well if you're just trying to warn a user that they've not finished filling out a single static form. For example:

But if your webpage or webapp is reasonably complex, these kinds of checks can get unwieldy. Sure, you can add more and more checks, but a good abstraction layer can help you and have other benefitsā€”which I'll get to later. šŸ‘·ā€ā™€ļø

So, let's build an abstraction layer around the Promise object, which represents the future result of work- like a response from a network fetch() .

The traditional way folks are taught promises is to think of them as a single operation, perhaps requiring several steps- fetch from the server, update the DOM, save to a database. However, by sharing the Promise , other code can leverage it to watch when it's finished.

Pending Work

Here's an example of keeping track of pending work. By calling addToPendingWork with a Promise ā€”for example, one returned from fetch() ā€”we'll control whether to warn the user that they're going to unload your page.

Now, all you need to do is call addToPendingWork(p) on a promise, maybe one returned from fetch() . This works well for network operations and such- they naturally return a Promise because you're blocked on something outside the webpage's control.

Busy Spinner

As I talked about in the video above šŸ“ŗšŸ”, we can also use the set of pending work to control a busy spinner. This is a pretty simple extension to the addToPendingWork function:

When a new Promise is added, we show the spinner (by setting its .hidden property to false ). And when any promise finishes, we detect if there's no more work at allā€” and hide the spinner if pendingOps is empty.

I'm not a UX designer, so building a visually appealing busy spinner is a UX exercise left for the reader! šŸ‘©ā€šŸŽØ

Pending Forms

But what about for the example above- a pending form? There's two options here. You could add a second beforeunload handler, just like the one at the top of this article: a simple boolean check.

But if you're interested in using the Promise mechanic even for a form, it turns out we can promisify the concept of a user completing a form. There's two parts to this idea.

First, we create our own Promise and add it to our pending work it when the user starts typing something:

Then, when the form is submitted (potentially via fetch() ), we can "resolve" that original promise with the result of the network operation:

And voilĆ  ! If the user has typed into the form, we can block the page from unloading, using the same pending work idiom as before. Of course, your busy spinner probably shouldn't say "Saving!".

Send a Beacon

I've covered a lot on pending work, listening to the completion of promise from a fetch() . But, as I mentioned in the video, you might not always need to prompt the user at all.

If you're making a network request which has no useful result- you're just sending it to a server, and you don't care about the result- you can use the modern browser call navigator.sendBeacon() . It literally has no return value, so you can't wait for its result (whether that be success or failure). But, it's explicitly designed to run even after a page is closed.

Of course, you don't have to use sendBeacon only in beforeunload ā€”you can use it before the page is closed, and then you might not have to implement a beforeunload handler at all, because you don't have a pending Promise to wait for!

If your browser doesn't support sendBeacon , it's almost exactly equal to sending a POST request via fetch() . You could fallback using code like this:

āš ļø It's even worth doing this if you're trying to make network requests in beforeunload , as some browsers will still succeed a fetch() even though the spec doesn't guarantee it.

Emoji Example

I use navigator.sendBeacon() to record when you select an emoji on Emojityper , to generate the 'trending' šŸ“ˆ list and emoji popularity šŸ”„. It's suitable there as I don't need to wait for a response, and the request can go out even as you're closing the page. šŸ˜‚šŸ‘

I hope you enjoyed this episode of The Standard and the slightly longer explanation!

Do you have questions? Please leave comments below, or contact me on Twitter . I'm also eager to hear your suggestions or improvements. šŸ•µļø

Top comments (34)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

yerycs profile image

  • Joined Dec 3, 2019

Thanks for good post. I have one error, I want your help.

beforeunload function does not work if there is no user interaction. It causes following error:

Blocked attempt to show a 'beforeunload' confirmation panel for a frame that never had a user gesture since its load.

How to show warning message even no user interaction?

Hoping your help. Thanks

samthor profile image

  • Location Sydney, Australia
  • Work ĀÆ\_(惄)_/ĀÆ
  • Joined Feb 6, 2018

Good observation, although I actually mentioned this in the article:

Showing a prompt isn't guaranteed. Just like playing audio on the web, browsers can ignore your request if a user hasn't interacted with your page.

This makes senseā€”a page that I've put into a background tab and then later closed shouldn't be able to get my attention!

Thanks for your reply.

Little trick. So, is it impossible to show warning message if there is no user interaction?

There's no harm in trying (a browser might decide that the page is allowed toā€”perhaps if your user has visited you a lot before) but it's unlikely to work. As per my post, maybe consider using sendBeacon if there's some information you want to exfiltrate from the page before it closes...

Even calling alert() is often disallowed in background pages (or at least delayed until the page gets focus again).

Let us assume.

I have passed complex page which has decades tests. After passing this page, I get into the test result page.

If I click back button without any interaction in browser, then it goes to test page without confirmation, and I lost test result and should pass complex test again.

I hope it can be resolved. Any Idea?

Yes, that will go "back", but there are lots of other ways to store state (like your test results) that don't rely on the user keeping a page open.

e.g., indexdb, local storage, building a SPA where 'back' is handled by your code, etc ...

Understand.

Thanks for your kindly help. Hoping your good post. :)

Do you think it is impossible to implement warning message without user interaction?

Yes, I think it's impossible. Allowing an annoying popup to be generated without the user ever using the page is against what browsers are aiming for.

Can you explain about "against what browser are aiming for"? Sorry for annoying. :)

maxart2501 profile image

  • Location Italy
  • Education Mathematics
  • Work Consultant at Antreem
  • Joined Jan 12, 2017

I've always found those notifications annoying but eh, they actually saved me a couple of times.

What's way worse in my opinions is showing those "don't miss this other content!" modals when the mouse cursor leaves the boundaries of the page. They should be outright banned! šŸ˜©

To stay on topic, I think sendBeacon is a great thing - too bad IE and mobile Safari don't support it šŸ™

karapapas profile image

  • Joined Mar 30, 2020

Hello! Great article on beforeunload.

I have a question though, is it possible to prevent page unload and stay on the page without prompting the user? Or, if that is not possible, to at least customize the confirmation dialog?

Thank you for your time!!

No, that's the whole point. You could write something like "CLOSING THIS PAGE WILL EXPLODE YOUR COMPUTER", and browsers have decided that you should not be able to do that.

oathkeeper profile image

  • Location Bhavnagar, Gujarat, India
  • Education B.Tech ICT
  • Work Software Engineer at Postman Inc
  • Joined Apr 5, 2018

How to ensure to know if a user has clicked on cancel on that alert? and Revert the action/API call that I was going to if user had proceeded to leave.

Inside your beforeunload handler, you can add code in a setTimeout ā€”probably even with a timeout of zero. That code will only run if the user allowed the page to stay open.

Ok so we are basically making it async?

Yeah, because your code otherwise won't have a chance to run.

I'd probably put a longer delay than zero on it, some browsers might let code execute even if the page is closing. I admit this behavior is a bit undefined.

tux0r profile image

  • Joined Jan 2, 2017

Yes, please annoy a user who wants to leave...

This feature exists on the web whether I write about it or not! :)

Hopefully this post has given some examples of when beforeunload is appropriate to use, and detailed a technical approach so that folks don't just generate warnings all the time. And you might also save your users' dataā€”if a network request is still pending while a page is being closed, beforeunload can be useful to ensure that it does complete successfully.

sleepyfran profile image

  • Location Prague, Czech Republic
  • Work Software Developer at Microsoft
  • Joined Aug 9, 2018

This is a super useful feature that saved me countless times in pages in which I'd lose all my progress if they didn't implement it. Of course this can be used in bad situations, just like many other features, but that doesn't mean that it can't be helpful sometimes too.

amsharma9 profile image

  • Location New Delhi
  • Work PHP Developer at Freelance
  • Joined Dec 10, 2019

I would like to know if I can differentiate between beforeunload happening when closing window and moving away from page etc. I need to logout the user when s/he closes the window but NOT when s/he is moving to another page etc.

I am using sendBeacon right now as ajax didn't work.

Moving to another page can be detected by watching focus or the Page Visibility API . The page is still open in that case, just hidden or not being used by the user.

sashirocks1 profile image

  • Joined Oct 9, 2020

I use the following piece of code in 'beforeunload' to delete a user session during logout, but this fails to clear the user session on a firefox browser, can you please help out here var req = new XMLHttpRequest(); req.open('DELETE', URI, true); req.setRequestHeader("TOKEN", $rootScope._TOKEN); req.send(null);

Don't send an XMLHttpRequest ā€”use sendBeacon , like I mentioned in the article.

jalson1982 profile image

  • Joined May 28, 2019

Any idea how to perform graphql mutation with sendBeacon?

Well, you send off a POST request with sendBeacon . You'd tell your server (on some HTTP handler) to do something, but you wouldn't be able to see whether the result was successful.

The issue with this I can not set headers or on some way control it. I am using synchronous XMLHttp request, it runs on all browsers but slows down a little navigation and it is not also the most happier solution. I do not need to see the result I just need to save analytics data to db on browser close.

kenny08gt profile image

  • Joined Jul 27, 2019

Thanks! this is very helpful, I wish it had an option to make an action when the user actually agree to leave, like delete localstorage.

You could do the action and revert it if your JS runs again.

samishakhurana profile image

  • Location India
  • Work Software Engineer at Quinbay
  • Joined Oct 21, 2020

Hi, Thanks for an insightful post. Is there any way I can track the click of leave button on this popup. If user click on cancel button we can use setTimeOut to do some operations, but in my case I want to do some final operation on click of leave button.

rudyhadoux profile image

  • Joined Sep 16, 2019

For Angular, @HostListener( 'window:beforeunload' ) seems not working for every browsers...

pinguinosod profile image

  • Location Graz, Austria
  • Joined Jul 4, 2018

Everything works fine, except when I try to create UI tests, seems like firefox doesn't trigger beforeunload when it is being controlled by an automated software.

Unfortunately, since the browser is entirely allowed to decide whether to show this message at all (e.g. if a tab has never had focus), it might not be something you can really test in an automated fashion. šŸ˜”

tachuong20121997 profile image

  • Location VietName
  • Joined Apr 8, 2020

I use Reactjs to build the app, and "beforeunload" doesn't seem to work on iphone safari

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

kanani_nirav profile image

Page Views Counter: Netlify Dynamic Site Challenge using Netlify Blobs

Kanani Nirav - May 11

aneeqakhan profile image

Import and Export locations on Google Maps

Aneeqa Khan - May 1

mohammadfaisal profile image

Why NVM is Tremendously Helpful for Web Developers

Mohammad Faisal - May 11

wewake-dev profile image

Page: DOMContentLoaded, load, beforeunload, unload

The lifecycle of an HTML page has three important events:

  • DOMContentLoaded ā€“ the browser fully loaded HTML, and the DOM tree is built, but external resources like pictures <img> and stylesheets may not yet have loaded.
  • load ā€“ not only HTML is loaded, but also all the external resources: images, styles etc.
  • beforeunload/unload ā€“ the user is leaving the page.

Each event may be useful:

  • DOMContentLoaded event ā€“ DOM is ready, so the handler can lookup DOM nodes, initialize the interface.
  • load event ā€“ external resources are loaded, so styles are applied, image sizes are known etc.
  • beforeunload event ā€“ the user is leaving: we can check if the user saved the changes and ask them whether they really want to leave.
  • unload ā€“ the user almost left, but we still can initiate some operations, such as sending out statistics.

Letā€™s explore the details of these events.

DOMContentLoaded

The DOMContentLoaded event happens on the document object.

We must use addEventListener to catch it:

For instance:

In the example, the DOMContentLoaded handler runs when the document is loaded, so it can see all the elements, including <img> below.

But it doesnā€™t wait for the image to load. So alert shows zero sizes.

At first sight, the DOMContentLoaded event is very simple. The DOM tree is ready ā€“ hereā€™s the event. There are few peculiarities though.

DOMContentLoaded and scripts

When the browser processes an HTML-document and comes across a <script> tag, it needs to execute before continuing building the DOM. Thatā€™s a precaution, as scripts may want to modify DOM, and even document.write into it, so DOMContentLoaded has to wait.

So DOMContentLoaded definitely happens after such scripts:

In the example above, we first see ā€œLibrary loadedā€¦ā€, and then ā€œDOM ready!ā€ (all scripts are executed).

There are two exceptions from this rule:

  • Scripts with the async attribute, that weā€™ll cover a bit later , donā€™t block DOMContentLoaded .
  • Scripts that are generated dynamically with document.createElement('script') and then added to the webpage also donā€™t block this event.

DOMContentLoaded and styles

External style sheets donā€™t affect DOM, so DOMContentLoaded does not wait for them.

But thereā€™s a pitfall. If we have a script after the style, then that script must wait until the stylesheet loads:

The reason for this is that the script may want to get coordinates and other style-dependent properties of elements, like in the example above. Naturally, it has to wait for styles to load.

As DOMContentLoaded waits for scripts, it now waits for styles before them as well.

Built-in browser autofill

Firefox, Chrome and Opera autofill forms on DOMContentLoaded .

For instance, if the page has a form with login and password, and the browser remembered the values, then on DOMContentLoaded it may try to autofill them (if approved by the user).

So if DOMContentLoaded is postponed by long-loading scripts, then autofill also awaits. You probably saw that on some sites (if you use browser autofill) ā€“ the login/password fields donā€™t get autofilled immediately, but thereā€™s a delay till the page fully loads. Thatā€™s actually the delay until the DOMContentLoaded event.

window.onload

The load event on the window object triggers when the whole page is loaded including styles, images and other resources. This event is available via the onload property.

The example below correctly shows image sizes, because window.onload waits for all images:

window.onunload

When a visitor leaves the page, the unload event triggers on window . We can do something there that doesnā€™t involve a delay, like closing related popup windows.

The notable exception is sending analytics.

Letā€™s say we gather data about how the page is used: mouse clicks, scrolls, viewed page areas, and so on.

Naturally, unload event is when the user leaves us, and weā€™d like to save the data on our server.

There exists a special navigator.sendBeacon(url, data) method for such needs, described in the specification https://w3c.github.io/beacon/ .

It sends the data in background. The transition to another page is not delayed: the browser leaves the page, but still performs sendBeacon .

Hereā€™s how to use it:

  • The request is sent as POST.
  • We can send not only a string, but also forms and other formats, as described in the chapter Fetch , but usually itā€™s a stringified object.
  • The data is limited by 64kb.

When the sendBeacon request is finished, the browser probably has already left the document, so thereā€™s no way to get server response (which is usually empty for analytics).

Thereā€™s also a keepalive flag for doing such ā€œafter-page-leftā€ requests in fetch method for generic network requests. You can find more information in the chapter Fetch API .

If we want to cancel the transition to another page, we canā€™t do it here. But we can use another event ā€“ onbeforeunload .

window.onbeforeunload

If a visitor initiated navigation away from the page or tries to close the window, the beforeunload handler asks for additional confirmation.

If we cancel the event, the browser may ask the visitor if they are sure.

You can try it by running this code and then reloading the page:

For historical reasons, returning a non-empty string also counts as canceling the event. Some time ago browsers used to show it as a message, but as the modern specification says, they shouldnā€™t.

Hereā€™s an example:

The behavior was changed, because some webmasters abused this event handler by showing misleading and annoying messages. So right now old browsers still may show it as a message, but aside of that ā€“ thereā€™s no way to customize the message shown to the user.

That may sound weird, but most browsers ignore event.preventDefault() .

Which means, following code may not work:

Instead, in such handlers one should set event.returnValue to a string to get the result similar to the code above:

What happens if we set the DOMContentLoaded handler after the document is loaded?

Naturally, it never runs.

There are cases when we are not sure whether the document is ready or not. Weā€™d like our function to execute when the DOM is loaded, be it now or later.

The document.readyState property tells us about the current loading state.

There are 3 possible values:

  • "loading" ā€“ the document is loading.
  • "interactive" ā€“ the document was fully read.
  • "complete" ā€“ the document was fully read and all resources (like images) are loaded too.

So we can check document.readyState and setup a handler or execute the code immediately if itā€™s ready.

Thereā€™s also the readystatechange event that triggers when the state changes, so we can print all these states like this:

The readystatechange event is an alternative mechanics of tracking the document loading state, it appeared long ago. Nowadays, it is rarely used.

Letā€™s see the full events flow for the completeness.

Hereā€™s a document with <iframe> , <img> and handlers that log events:

The working example is in the sandbox .

The typical output:

  • [1] initial readyState:loading
  • [2] readyState:interactive
  • [2] DOMContentLoaded
  • [3] iframe onload
  • [4] img onload
  • [4] readyState:complete
  • [4] window onload

The numbers in square brackets denote the approximate time of when it happens. Events labeled with the same digit happen approximately at the same time (Ā± a few ms).

  • document.readyState becomes interactive right before DOMContentLoaded . These two things actually mean the same.
  • document.readyState becomes complete when all resources ( iframe and img ) are loaded. Here we can see that it happens in about the same time as img.onload ( img is the last resource) and window.onload . Switching to complete state means the same as window.onload . The difference is that window.onload always works after all other load handlers.

Page load events:

  • Script such as <script>...</script> or <script src="..."></script> block DOMContentLoaded, the browser waits for them to execute.
  • Images and other resources may also still continue loading.
  • The load event on window triggers when the page and all resources are loaded. We rarely use it, because thereā€™s usually no need to wait for so long.
  • The beforeunload event on window triggers when the user wants to leave the page. If we cancel the event, browser asks whether the user really wants to leave (e.g we have unsaved changes).
  • The unload event on window triggers when the user is finally leaving, in the handler we can only do simple things that do not involve delays or asking a user. Because of that limitation, itā€™s rarely used. We can send out a network request with navigator.sendBeacon .
  • loading ā€“ the document is loading.
  • interactive ā€“ the document is parsed, happens at about the same time as DOMContentLoaded , but before it.
  • complete ā€“ the document and resources are loaded, happens at about the same time as window.onload , but before it.
  • If you have suggestions what to improve - please submit a GitHub issue or a pull request instead of commenting.
  • If you can't understand something in the article ā€“ please elaborate.
  • To insert few words of code, use the <code> tag, for several lines ā€“ wrap them in <pre> tag, for more than 10 lines ā€“ use a sandbox ( plnkr , jsbin , codepen ā€¦)

Lesson navigation

  • Ā© 2007ā€”2024  Ilya Kantor
  • about the project
  • terms of usage
  • privacy policy

Safari 15 prompts the beforeunload alert, but does not block navigation

Using the example provided by MDN, the beforeunload event is working in my Safari browser:

(I first must click into the window to make sure the browser detects interaction.)

  • if I close the browser window, the alert blocks the window from being closed
  • If I navigate to another page, the alert is shown
  • However, when I navigate to another page, the alert does not block navigation.

I am taken to the new page with the alert still being displayed. The alert is then "useless" in the sense that pressing the affirmative or negative buttons dismisses the alert, but has no other effect. This is not the expected behavior in Chrome or Firefox. In these, the page will not navigate or cancel navigation until an alert option is clicked.

Is there any work-around? It seems it would be better to not show the alert at all than to show the alert while asynchronously unloading the current page and loading another page.

I need to use this event to inform a user they may want to save changes to a document before leaving the page. This was the original use case for beforeunload.

!!! It's very important in this test to wait and watch the alert. The behavior I describe is navigation, so we must wait for the link to resolve and page GET to commence before you see this issue.

!!!! This only happens when clicking on a bookmarked link. If you type some link into the navigation bar, it behaves as expected.

Specifically this applies to CACHED pages only.

This is the kind of defect you might not catch in automation testing, because unless there is a pause after the alert is shown, the test might pass.

  • Skip to main content
  • Select language
  • Skip to search

WindowEventHandlers.onbeforeunload

The WindowEventHandlers.onbeforeunload event handler property contains the code executed when the beforeunload is sent. This event fires when a window is about to unload its resources. The document is still visible and the event is still cancelable.

Note: Ā To combatĀ unwanted pop-ups, some browsers don't display prompts created in beforeunload event handlers unless the page has been interacted with; some don't display them at all. For a list of specific browsers, see the Browser_compatibility section.

  • funcRef is a reference to a function or a function expression.
  • The function should assign a string value to the returnValue property of the Event object and return the same string.

When this event returns (or sets the returnValue property to) a value other than null or undefined , the user is prompted to confirm the page unload. In some browsers, the return value of the event is displayed in this dialog. Starting with Firefox 4, Chrome 51, Opera 38 and Safari 9.1, a generic string not under the control of the webpage will be shown instead of the returned string. For example, Firefox displays the string "This page is asking you to confirm that you want to leave - data you have entered may not be saved."Ā See bugĀ 588292 and Chrome Platform Status .

Since 25 May 2011, the HTML5 specification states that calls to window.alert() , window.confirm() , and window.prompt() methods may be ignored during this event. See the HTML5 specification for more details.

Note also, that various browsers ignore the result of the event and do not ask the user for confirmation at all. The document will always be unloaded automatically. Firefox has a switch named dom.disable_beforeunload in about:config to enable this behaviour.

You can and should handle this event through window.addEventListener() and the beforeunload event. More documentation is available there.

Binding to this event can be used to prevent the browser from fully caching the page in cases where content is rendered by javascript. In certain circumstances when returning to a page that has executed javascript in order to populate content, you may find the javascript not running upon the return visit when navigating back. If window.onbeforeunload has been bound (and thus triggered when leaving that page) javascript in the page will be triggered on the subsequent return visit and therefore update the content.

Specifications

The event was originally introduced by Microsoft in Internet Explorer 4 and standardized in the HTML5 specification.

Browser compatibility

  • MSDN: onbeforeunload event

Document Tags and Contributors

  • Event Handler
  • WindowEventHandlers
  • onafterprint
  • onbeforeprint
  • onbeforeunload
  • onhashchange
  • onlanguagechange
  • onrejectionhandled
  • onunhandledrejection
  • HTMLBodyElement
  • HTMLFrameSetElement
  • autocomplete
  • autocompleteerror
  • DOMContentLoaded
  • afterscriptexecute
  • beforeprint
  • beforescriptexecute
  • beforeunload
  • contextmenu
  • languagechange
  • readystatechange
  • loadedmetadata
  • canplaythrough
  • volumechange
  • durationchange
  • unhandledrejection
  • rejectionhandled
  • BeforeUnloadEvent
  • DOMStringMap
  • GlobalEventHandlers
  • HTMLAnchorElement
  • HTMLAreaElement
  • HTMLAudioElement
  • HTMLBRElement
  • HTMLBaseElement
  • HTMLBaseFontElement
  • HTMLButtonElement
  • HTMLCanvasElement
  • HTMLContentElement
  • HTMLDListElement
  • HTMLDataElement
  • HTMLDataListElement
  • HTMLDialogElement
  • HTMLDivElement
  • HTMLDocument
  • HTMLElement
  • HTMLEmbedElement
  • HTMLFieldSetElement
  • HTMLFormControlsCollection
  • HTMLFormElement
  • HTMLHRElement
  • HTMLHeadElement
  • HTMLHeadingElement
  • HTMLHtmlElement
  • HTMLIFrameElement
  • HTMLImageElement
  • HTMLInputElement
  • HTMLIsIndexElement
  • HTMLKeygenElement
  • HTMLLIElement
  • HTMLLabelElement
  • HTMLLegendElement
  • HTMLLinkElement
  • HTMLMapElement
  • HTMLMediaElement
  • HTMLMetaElement
  • HTMLMeterElement
  • HTMLModElement
  • HTMLOListElement
  • HTMLObjectElement
  • HTMLOptGroupElement
  • HTMLOptionElement
  • HTMLOptionsCollection
  • HTMLOutputElement
  • HTMLParagraphElement
  • HTMLParamElement
  • HTMLPictureElement
  • HTMLPreElement
  • HTMLProgressElement
  • HTMLQuoteElement
  • HTMLScriptElement
  • HTMLSelectElement
  • HTMLShadowElement
  • HTMLSourceElement
  • HTMLSpanElement
  • HTMLStyleElement
  • HTMLTableCaptionElement
  • HTMLTableCellElement
  • HTMLTableColElement
  • HTMLTableDataCellElement
  • HTMLTableElement
  • HTMLTableHeaderCellElement
  • HTMLTableRowElement
  • HTMLTableSectionElement
  • HTMLTemplateElement
  • HTMLTextAreaElement
  • HTMLTimeElement
  • HTMLTitleElement
  • HTMLTrackElement
  • HTMLUListElement
  • HTMLUnknownElement
  • HTMLVideoElement
  • HashChangeEvent
  • MessageChannel
  • MessageEvent
  • MessagePort
  • NavigatorGeolocation
  • NavigatorID
  • NavigatorLanguage
  • NavigatorOnLine
  • NavigatorPlugins
  • PageTransitionEvent
  • PluginArray
  • PopStateEvent
  • PortCollection
  • PromiseRejectionEvent
  • RadioNodeList
  • Transferable
  • ValidityState
  • WindowBase64
  • WindowTimers

beforeunloadevent api

Beforeunloadevent api: returnvalue, beforeunloadevent api: user interaction required for dialog box, window api: `beforeunload` event, window api: `beforeunload` event: activation by setting `event.returnvalue` to any truthy value, window api: `beforeunload` event: dialog displays a generic string, not event handler return value, window api: `beforeunload` event: activation using `event.preventdefault()`, window api: `beforeunload` event: activation by returning a string.

JS Reference

Html events, html objects, other references, onbeforeunload event.

Call a function when the page is about to be unloaded:

Description

The onbeforeunload event occurs when a document is about to be unloaded .

This event allows you to display a message in a confirmation dialog box to inform the user whether he/she wants to stay or leave the current page.

The default message that appears in the confirmation box, is different in different browsers. However, the standard message is something like "Are you sure you want to leave this page?".

This message cannot be removed, unless you call preventDefault() on the event.

Advertisement

In JavaScript:

In JavaScript, using the addEventListener() method:

Technical Details

Browser support.

onbeforeunload is a DOM Level 2 (2001) feature.

It is fully supported in all browsers:

Get Certified

COLOR PICKER

colorpicker

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail: [email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail: [email protected]

Top Tutorials

Top references, top examples, get certified.

  • EspaƱol ā€“ AmĆ©rica Latina
  • PortuguĆŖs ā€“ Brasil
  • TiĆŖĢng ViĆŖĢ£t
  • Web Platform

Deprecating the unload event

DemiƔn Renzulli

The unload event will be gradually deprecated by gradually changing the default so that unload handlers stop firing on pages unless a page explicitly opts in to re-enable them.

Deprecation timeline

We noted that unload behavior would likely be subject to changes as early as January 2019, when we announced our intent to implement a back/forward cache . In parallel to the implementation work, we conducted a large outreach which resulted in a significant drop of unload usage . To complement this outreach, we also started to offer ways to test the effect of deprecating unload from Chrome 115:

  • In the wild testing via the Permission-Policy API for unload in Chrome 115 (July 2023)
  • Local testing by enabling a flag in Chrome 117 (September 2023)

Following these outreach and trial phases, here is how we expect the soft deprecation to roll out:

  • Starting with 1% of users from Chrome 120 (end of November 2023).
  • Ending with 100% of users by the end of Q3 2024
  • In addition, from Q3 2024, we intend to start a generic phase where unload will gradually cease to function on any sites, starting with 1% of users and ending with 100% of users by the end of Q1 2025.

Note that we also offer a menu of opt-out options in case this soft deprecation timeline doesn't provide sufficient time to migrate away from unload. Our goal is to use this soft deprecation to inform the timeline for the last phase ( hard deprecation of unload ) in which these opt-outs will be removed or reduced.

Timeline of the unload deprecation.

unload was designed to fire when the document is being unloaded. In theory, it can be used to run code any time a user is navigating away from a page, or as an end of session callback.

Scenarios where this event was most commonly used include:

  • Saving user data : Save data before leaving the page.
  • Performing cleanup tasks : Closing open resources before abandoning the page.
  • Sending analytics : Sending data related to user interactions at the end of the session.

However the unload event is extremely unreliable .

On desktop Chrome and Firefox, unload is reasonably reliable but it has a negative impact on a site's performance by preventing the usage of bfcache (back/forward cache) .

On mobile browsers unload often doesn't run as tabs are frequently backgrounded and then killed. For this reason browsers choose to prioritize the bfcache on mobile over unload , making them even more unreliable. Safari also uses this behaviour on desktop.

The Chrome team believe using the mobile model of prioritizing bfcache over unload on desktop would be disruptive by making it more unreliable there too, when previously this has been reasonably reliable in Chrome (and Firefox). Instead, Chrome's aim is to remove the unload event completely. Until then it will remain reliable on desktop for those who have explicitly opted-out of the deprecation.

Why deprecate the unload event?

Deprecating unload is a key step in a much bigger recognition of the web we live in now. The unload event gives a false sense of control of the app lifecycle that is increasingly untrue of how we browse the web in the modern computing world.

Mobile operating systems frequently freeze or unload web pages to conserve memory and desktop browsers are doing this more and more now too for the same reasons. Even without operating system interventions, users themselves frequently tab switch and kill old tabs without formally "leaving pages".

Removing the unload event as obselete is a recognition that we as web developers need to ensure our paradigm matches that of the real world and not depend on outdated concepts that no longer hold trueā€”if they ever did.

Alternatives to unload events

Instead of unload it is recommended to use:

  • visibilitychange : To determine when the visibility of a page changes. This event happens when the user switches tabs, minimizes the browser window, or opens a new page. Consider the hidden state the last reliable time to save app and user data.
  • pagehide : To determine when the user has navigated away from the page. This event happens when the user navigates away from the page, reloads the page, or closes the browser window. The pagehide event is not fired when the page is simply minimized or switched to another tab. Note that, as pagehide does not make a page ineligible for the back/forward cache, it is possible a page can be restored after this event fires. If you're cleaning up any resources in this event, then they may have to be restored on page restore.

The beforeunload event has a slightly different use case to unload in that it is a cancellable event. It is often used to warn users of unsaved changes when navigating away. This event is also unrealiable as it will not fire if a background tab is killed. It is recommended to limit use of beforeunload and only add it conditionally . Instead, use the above events for most unload replacements.

For more details, see this advice on never using the unload handler .

Detect usage of unload

There are different tools to help you find appearances of the unload event on pages. This allows sites to discover if they are using this eventā€”either in their own code, or via librariesā€”and so may be affected by the upcoming deprecation.

Lighthouse has a no-unload-listeners audit , which warns developers if any JavaScript on their pages (including that from third-party libraries) adds an unload event listener.

Lighthouse audit showing unload handlers in use

Chrome DevTools

Chrome DevTools includes a back-foward-cache audit to help you identify issues that may prevent your page from being eligible for back/forward cache, including the usage of the unload handler.

To test back/forward cache, follow these steps:

On your page, open DevTools , then navigate to Application > Background services > Back/forward cache .

Click Test back/forward cache Chrome automatically takes you to chrome://terms/ and back to your page. Alternatively, you can click the browser's back and forward buttons.

If your page isn't eligible for back/forward caching, the Back/forward cache tab shows you a list of issues. Under Actionable , you can see if you are using unload :

Chrome DevTools Back/forward cache testing tool showing an unload handler was used

Reporting API

The Reporting API can be used to in conjuction with a read-only Permission Policy to detect usage of unload from your website users.

For more details see usUsing Reporting API to find unloads

Bfcache notRestoredReasons API

The notRestoredReasons property ā€”added to the PerformanceNavigationTiming classā€”reports information on whether documents were blocked from using the bfcache on navigation, and why. Usage instructions can be found here . This is an example of how the response object warning of an existing unload listener looks like:

Control access to unload

Chrome will deprecate the unload event gradually. In the meantime, you can use different tools to control this behavior and prepare for the upcoming deprecation. Keep in mind that you should not rely on these techniques in the long term, and you should plan to migrate to the alternatives instead as soon as possible.

The following options allow you to enable or disable unload handlers to test how your site would work without them so you can prepare for the upcoming deprecation. There are different types of policies:

  • Permissions Policy : This is a platform API for site owners to control access to features, at a site or an individual page level, via the usage of HTTP headers.
  • Enterprise policies : Tools for IT admins to configure Chrome for their organization or business. They can be configured via an admin panel, like the Google Admin Console .
  • Chrome flags : This allows an individual developer to change the unload deprecation setting to test impact on various sites.

Permissions Policy

A Permissions Policy has been added from Chrome 115 to allow sites to opt-out of using unload handlers and immediately benefit from the bfcache to improve site performance. See these examples on how to set this for your site . This allows sites to get ahead of the unload deprecation.

This will be extended in Chrome 117 to allow sites to do the reverse, and to opt-in to continuing to try to fire unload handlers, as Chrome changes the default for these to not fire in future. See these examples on how to continue to allow unload handlers to fire for your site . This opt-in will not remain forever and should be used to allow time for sites to migrate away from unload handlers.

Enterprise policy

Enterprises that have software that depends on the unload event to function correctly can use the ForcePermissionPolicyUnloadDefaultEnabled policy to prevent the gradual deprecation for devices under their control. By enabling this policy, unload will continue to default to enabled for all origins. A page may still set a stricter policy if it wants. Like the Permissions Policy opt-out, this is a tool to mitigate potential breaking changes, but it should not be used indefinitely.

Chrome flags and command line switches

As well as the enterprise policy, you can disable the deprecation for individual users via the Chrome flags and command lines swtiches:

Setting chrome://flags/#deprecate-unload this to enabled will bring forward the deprecation default and prevent unload handlers from firing. They can still be overridden on a site-by-site basis via Permissions Policy, but will continue to fire by default.

These settings can be also be controlled by command line switches .

Options comparison

The following table summarizes the different uses of the options discussed previously:

unload handlers are being deprecated. They have been unreliable for a long time and are not guaranteed to be fired on all cases where a document gets destroyed. Additionally, unload handlers are incompatible with bfcache .

Sites that currently make use of unload handlers should prepare for this upcoming deprecation by testing for any existing unload handlers, removing or migrating them or, as a last resort, delaying the deprecation if more time is needed.

Acknowledgements

Thanks to Kenji Baheux, Fergal Daly, Adriana Jara, and Jeremy Wagner for help reviewing this article.

Hero image by Anja Bauermann on Unsplash

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License , and code samples are licensed under the Apache 2.0 License . For details, see the Google Developers Site Policies . Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2023-11-03 UTC.

How to Fix Javascript onbeforeunload not working

Ever had problems with onbeforeunload not triggering? Check out steps to fix this in this post!

šŸ”” Table of contents

Introduction.

Did you ever needed to perform certain action before the user leaves your website. To do this we can use the onbeforeunload event.

Recently, I had to implement this for one of my Vue apps. So when the user closes the page, we handle onbeforeunload to save their temporary data.

This lead me down a rabbit hole of different issues.

This post will go over fixes on why your onbeforeunload event handler is not working. To fix onbeforeunload issues, we can try the following:

  • Check that you are using the onbeforeunload syntax correctly
  • Make sure we have returned a value
  • Check for browser compatibility
  • Know when to use and the limitations of onbeforeunload
What is the onbeforeunload exactly? The onbeforeunload event in JavaScript is fired when the document, or a specific element, is about to be unloaded. When we have attached a handler to this event, a confirmation will open up asking the user if they want to navigate away from the browser!

If you find yourself in a scenario where the onbeforeunload is not loading correctly, consider the below steps to fix that up:

1. Check that you are using the onbeforeunload syntax correctly

One thing that can stump you when trying to get the onbeforeunload event working is that you are not using the syntax correctly.

According to MDN ( https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event ) we can do in JavaScript like so:

We can do it in the following HTML as well:

A few gotchas to keep in mind

There are a few gotchas to keep in mind when working with this beforeunload event though:

  • The following global methods will not work: window.alert() , window.confirm() , and window.prompt()
  • With modern browsers, we cannot change the dialog text that comes up (eg ā€œLeave site - Changes you made may not be saved!")

leave site message in chrome

The even will fire if there has been user interaction on the site. If theres no interaction, then this will not fire!

If you did not call the preventDefault() on the event, the dialog will not appear. However the code in the event handler will run!

Tip: Mobile unload

To avoid issues with reloading on mobile (from the user accidentally swiping or dragging content - eg google maps, tables), we can use CSS to stop the scroll y behaviour:

The above just sets the behavior of scroll y to overscroll-behavior-y: contain . This means it will stop scroll chaining which can cause page reloads!

2. Make sure we have returned a value

A key note when handling the onbeforeunload event, is that we have a return value.

So in our event handler for beforeunload, make sure to have the line return event.returnValue = ''

The return value and the preventDefault method controls if the dialog will appear. So it may seem that your onbeforeunload is not working, but in fact it is still executing the code in the handler - just not showing the dialog!

3. Check for browser compatibility

Browser support for this has a history of flakyness. Some of the inconsistencies and weirdness that you will need to consider:

  • Different browsers will have different dialog text.

Firefox will use: ā€œThis page is asking you to confirm that you want to leave - data you have entered may not be saved.ā€

Chrome displays the string, ā€œDo you want to leave the site? Changes you made may not be saved.ā€ (see Chrome Platform Status).

  • The browser will show a dialog warning to the user only when event.returnValue has a value. Now to skip the prompt we will have to use null - but for IE we have to use undefined (it will show the ā€œnullā€ text if not used)!

The addEventListener is the preferred way to add a handler to the beforeunload event. However with older browsers (eg IE6, IE7) you can use attachEvent .

4. Know when to use and the limitations of onbeforeunload

One of the limitations of beforeunload and unload events is that it does not work well with the browser back buttons (also known as back/forward cache: https://web.dev/bfcache/ )

When you have unload/beforeunload event handlers, browsers will not place pages in the bfcache - so could stuff you up if you are somehow catering for the user going back and forth.

Additionally, there are a few quirkyness for when the handler will trigger.

As an example, Pressing F5 to refresh the page counts as a user interaction and kick-of the beforeunload event handler. But if the user clicks the refresh button instead, it does not register as a user interaction and therefore wont fire the event (as of Chrome 81).

From my experience to get around browser issues, its best to register the event handler for onbeforeunload on the <body> HTML tag. Less messing around with adding/ removing handlers or considering using addEventListener vs attachEvent

Alternatives for onbeforeunload - using pageshow/ pagehide methods

Now for certain browsers, the behaviour of onbeforeunload can be shaky - especially on Safari, iOS, Firefox.

We can try to use the pageshow/ pagehide events ( https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event )

The above code provides more options for us - it allows us to check if the page is being ā€œsuspendedā€ (eg the user navigating away) or destroyed (user actually closing the page)

If you want to further make it cross browser, we can do a check support condition like the following:

In the above, we are checking if the browser supports onpagehide - if it does then use the pagehide/ pageshow events. If not, fallback to the unload/load events!

Cancelling the window.onbeforeunload event

We canā€™t really cancel the the onbeforeunload event due to security reasons. However, we can unregister the event from your HTML element.

So instead of adding the event handler to a global window object like the below:

Best practice to first create a handler method that we can reference and then add or remove it conditionally:

The onbeforeunload event is great for you to attach a piece of code before the user exits your webpage. In most cases we want to save any unsaved data from the user so that they can continue where they left off later.

However there are some gotchas when dealing with this event - since it can be unreliable. To fix issues of the onbeforeunload not working for our page, we can:

  • check to see if we are using the syntax correctly, using the event.preventDefault and returning event.returnValue
  • Verify that you are not relying on the prompts window.alert() , window.confirm() , and window.prompt() - these will be ignored
  • Check browser compatibility and consider the pagehide/ pageshow events
  • Consider conditionally adding event handlers to the onbeforeunload instead of adding it automattically for performance improvements!

šŸ‘‹ About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember šŸ˜…)

Follow along on Twitter , GitHub and YouTube

šŸ‘‰ See Also šŸ‘ˆ

  • How to create a Harvest Moon game with HTML - Part 1
  • HTML mailto can have multiple addresses, subject and email body
  • [Fixed] await is only valid in async functions and the top level bodies of modules
  • [How To] Javascript format date to dd mm yyyy in 2023
  • How to fix SyntaxError Unexpected Token in JSON
  • Fixing DataTables Pagination CSS not working correctly

Navigation Menu

Search code, repositories, users, issues, pull requests..., provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . Weā€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onbeforeunload is not supported on iOS #4933

@r-l-x

r-l-x commented May 24, 2019

  • šŸ‘ 3 reactions

@Fyrd

No branches or pull requests

@Fyrd

IMAGES

  1. Top 5 Safari Browser Alternatives in iPhone

    safari onbeforeunload alternative

  2. How to Download and Install Safari on Windows 11

    safari onbeforeunload alternative

  3. iOS: Best Alternatives to Safari for iOS Users

    safari onbeforeunload alternative

  4. javascript

    safari onbeforeunload alternative

  5. CSS : Safari: onbeforeunload

    safari onbeforeunload alternative

  6. 7 Best Mozilla Firefox Alternatives To Browse The Internet

    safari onbeforeunload alternative

VIDEO

  1. all safari no flaps

  2. How to Download Apps from Safari

  3. Tiger 31150 Alternate Build Lego MOC Tutorial Instructions

  4. Google Chrome (Mobil)

  5. Safari is AI Now!

  6. SafariLIVE Sunrise

COMMENTS

  1. Is there an alternative method to use onbeforeunload in mobile safari?

    Is there an alternative method to use instead of onbeforeunload in mobile-safari? I've noticed that Google was able to capture the onbeforeunload event in mobile-safari. Has anyone figured out how they are doing so? Google was able to do so using their gmail client.

  2. window.onbeforeunload not working on the iPad?

    I have found that the onunload() event does fire. It's behavior is somewhat odd; whatever you have in your callback function attached to the event is actually run after the new page has loaded in the background (You can't tell it's loaded yet, but server logging will show that it has).

  3. Window: beforeunload event

    The beforeunload event is fired when the current window, contained document, and associated resources are about to be unloaded. The document is still visible and the event is still cancelable at this point. The main use case for this event is to trigger a browser-generated confirmation dialog that asks users to confirm if they really want to leave the page when they try to close or reload it ...

  4. Sure you want to leave?ā€”browser beforeunload event

    If you want to prompt or warn your user that they're going to close your page, you need to add code that sets .returnValue on a beforeunload event: window.addEventListener('beforeunload', (event) => { event.returnValue = `Are you sure you want to leave?`; }); There's two things to remember.

  5. Page: DOMContentLoaded, load, beforeunload, unload

    beforeunload/unload - the user is leaving the page. Each event may be useful: DOMContentLoaded event - DOM is ready, so the handler can lookup DOM nodes, initialize the interface. load event - external resources are loaded, so styles are applied, image sizes are known etc. beforeunload event - the user is leaving: we can check if the ...

  6. onbeforeunload alternative

    Please Reply who know the alternative for onbeforeunload code..which can cover the ios device..The code im using is here. $ (document).on ("pagehide",function () {} Hope someone help me on this. šŸ™‚. Thanks! WebKit. 1.9k. Posted 8 years ago by. camilleForbes22. Same here ()

  7. Safari 15 prompts the beforeunloadā€¦

    Safari 15 prompts the beforeunload alert, but does not block navigation. Using the example provided by MDN, the beforeunload event is working in my Safari browser: const beforeUnloadListener = ( event) => {. event .preventDefault();

  8. WindowEventHandlers.onbeforeunload

    Handlers. .onbeforeunload. The WindowEventHandlers.onbeforeunload event handler property contains the code executed when the beforeunload is sent. This event fires when a window is about to unload its resources. The document is still visible and the event is still cancelable. Note: To combat unwanted pop-ups, some browsers don't display prompts ...

  9. Fixing addEventListener not working with beforeunload

    Using addEventListener with 'beforeunload' is generally considered better practice because it allows you to add multiple event handlers for the same event, whereas onbeforeunload only allows one. Another disadvantage of using "onbeforeunload" is that if you assign a new function to it - the old handler will be overwritten. 2.

  10. BeforeUnloadEvent

    Inherits properties from its parent, Event. returnValue Deprecated. When set to a truthy value, triggers a browser-controlled confirmation dialog asking users to confirm if they want to leave the page when they try to close or reload it. This is a legacy feature, and best practice is to trigger the dialog by invoking event.preventDefault(), while also setting returnValue to support legacy cases.

  11. "beforeunload"

    Window API: beforeunload event: Dialog displays a generic string, not event handler return value. "Can I use" provides up-to-date browser support tables for support of front-end web technologies on desktop and mobile web browsers.

  12. Window: unload event

    The unload event is fired when the document or a child resource is being unloaded. It is fired after: beforeunload (cancelable event) pagehide. The document is in the following state: All the resources still exist (img, iframe etc.) Nothing is visible anymore to the end user. UI interactions are ineffective ( window.open, alert, confirm, etc.)

  13. onbeforeunload Event

    Description. The onbeforeunload event occurs when a document is about to be unloaded. This event allows you to display a message in a confirmation dialog box to inform the user whether he/she wants to stay or leave the current page. The default message that appears in the confirmation box, is different in different browsers.

  14. Deprecating the unload event

    Alternatives to unload events. Instead of unload it is recommended to use: visibilitychange: To determine when the visibility of a page changes. This event happens when the user switches tabs, minimizes the browser window, or opens a new page. Consider the hidden state the last reliable time to save app and user data.

  15. How to Fix Javascript onbeforeunload not working

    Tip: Mobile unload. 2. Make sure we have returned a value. 3. Check for browser compatibility. 4. Know when to use and the limitations of onbeforeunload. Alternatives for onbeforeunload - using pageshow/ pagehide methods. Cancelling the window.onbeforeunload event.

  16. Window: pagehide event

    Window: pagehide event. The pagehide event is sent to a Window when the browser hides the current page in the process of presenting a different page from the session's history. For example, when the user clicks the browser's Back button, the current page receives a pagehide event before the previous page is shown.

  17. beforeunload not working in iOS browsers #11

    philipwalton commented on Jan 29, 2021. As far as I know, Safari on iOS (which includes the WebView used by Chrome) does not fire the beforeunload event. In other words, this is not something this library can prevent. šŸ‘ 5.

  18. Difference between onbeforeunload and onunload

    onbeforeunload:. Called before unloading begins; MDN tells me you can cancel the closing of the page using event.preventDefault();; or by returning a non-void value (ie a value != 0), the page will pop up a confirmation dialog that allows the user to choose to cancel the close

  19. onbeforeunload is not supported on iOS #4933

    iOS Safari doesn't generate beforeunload events. This also applies to Firefox and Chrome on iOS as they are based on the Safari engine. Reference: Events supported by Safari on iOS: https://develop...

  20. window:beforeunload' event not working in Safari 14

    Seems indeed to be horribly broken in Safari 14. I only randomly see the beforeunload handler being fired. Tried a lot of things: clicking in the window, changing field inputs, changing URL with random GET params etc.