Vaadin onbeforeunload event - javascript

Is there any Out Of the Box Vaadin 10 (and higher) event similar to window.onbeforeunload in JavaScript?
I've tried to use onDetach() or beforeLeave(), but it only works inside UI, and when user reloads the page or closes the page it's not working.

You can use the approach described in https://vaadin.com/forum/thread/17523194/unsaved-changes-detect-page-exit-or-reload that was already suggested in a comment.
At the same time, I'd urge you to be really careful with beforeunload events since they are in some situations fired even though the user is actually not navigating away from the page.
The most common case is if the user clicks a link that starts a download. In that case the browser will fire the event immediately when the user clicks the link. Slightly later when the browser receives the response headers, it will discover that it's a download and not a new HTML page to display. The end result is then that beforeunload has been fired but the previous page is still kept running.
If you want to use the event for cleanup, then the best approach today is probably a combination of the unload event and then using the new-ish Beacon API for notifying the server that the user has actually navigated away. Integrating this into a Vaadin application will require slightly more JavaScript, but it has the benefit that it will actually work.

Related

Best way to detect browser window changes like go back, url change, reload, close event

So I am working on a testing application and I need to call a finsihTheTest() function (i.e. this function finishes the test by saving answers, time and other information) whenever following conditions occur:
User tries to reload page.
User tries to go back from the page.
User tries to close the tab.
User tries to close the browser window.
User goes to another url.
If anything happens that closes the page like laptop/PC shutdown, internet lost or anything else.
What I exactly want to do is, if once a user starts the test and by any mean he attempts to leave I want to save his state. Which is being done by the function finishTheTest().
I got a clue but it didn't work:
function UnLoadWindow() {
return 'We strongly recommends NOT closing this window yet.'
}
window.onbeforeunload = UnLoadWindow;
To get the full results for your cases there's many things you should now on how browsers react on many scenarios.
To understand more please read this section :
Especially on mobile, the unload event is not reliably fired. For example, the unload event is not fired at all in the following scenario:
A mobile user visits your page.
The user then switches to a different app.
Later, the user closes the browser from the app manager.
Also, the unload event is not compatible with the back/forward cache (bfcache), because many pages using this event assume that the page will not continue to exist after the event is fired. To combat this, some browsers (such as Firefox) will not place pages in the bfcache if they have unload listeners, and this is bad for performance. Others, such as Chrome, will not fire the unload when a user navigates away.
If you're specifically trying to detect page unload events, it's best to listen for the pagehide event.
window.addEventListener('pagehide', function(event) {
document.cookie = "saveData=test"
},false)
This way you can save your user current data and reload it on next page window load event

Detect Page Refresh or Navigation in Browser

I have a web app where a parent page displaying a list of records opens up a new tab ('child') to edit a clicked-on record. I want to track who has a page open, so I can display a message if more than one person is editing a unique record. This means reporting when a page is closed. I have assigned each page a GUID to facilitate recognition of the page instance.
So javascript in the browser needs to detect several scenarios:
browser tab closed
browser refresh
browser navigation to hyperlink
browser navigation forward/back
At the moment, all of these appear to trigger the window.onbeforeunload event. However I use this event to warn of changes in the underlying data, which means the event returns the confirmation text, and there is no way of knowing in this event if the user subsequently confirms or cancels the page unload. So I can't use this event to track page closure.
According to a number of sources the window.onunload event should be triggered in all of the above scenarios (and if it was, I could use it), but testing under Chrome on Windows is only triggering this event in scenario 1 (when the tab is closed). It works fine for that.
I'm pretty surprised by the lack of information around this - surely it's a bread and butter requirement in modern sites?
Has window.onunload been deprecated lately in some scenarios, or in some scenarios in some browsers? Without a reliable hook that takes place when the page is about to be replaced with some other information, it's impossible to monitor closing of a page. Any other workarounds?
I know that the two unload events suppress blocking functions (such as alerts) in the handler. However they appear to do hit breakpoints, do a console.log and allow Ajax calls just fine. I'm pretty sure they are not being fired in events 2,3 and 4 - it's not just that my debugging is being blocked.
While there appear to be answers on SO already (most of which don't work or are deprecated), I posted this because browser events are a shifting-sands scenario as security issues evolve, so I wanted to find out where we are in 2021.
Actually, it looks as if this might be the solution: https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event
Google discourages use of the unload event because it is (a) unreliable on mobiles and (b) blocks the caching of pages. It is also advised to only add the beforeunload event just before it is used, and to remove it afterwards, because it also blocks the caching of pages (I note that this is not really practical for me, however, as I use it to guard against unintentional closing of a page after a possibly significant amount of data has been entered, and this could happen at any moment).
So as of July 2018, and still best practice as of July 2021, this would be the recommended way to detect the unloading of a page:
const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
addEventListener(terminationEvent, function(event) {
// handler code here ...
}, { capture: true });
This has been tested in a small ASP NET Core project using an AJAX callback to report the page termination, and appears to work reliably in Chrome and Edge. Also works in IE11 as long as
<meta http-equiv="x-ua-compatible" content="IE=edge">
is present.

What can be the event similar to onpopstate that works across documents?

From mozilla docs:
A popstate event is dispatched to the window every time the active
history entry changes between two history entries for the SAME
DOCUMENT.
Which window event should i use if i need to listen to 'session history changes' ACROSS DOCUMENTS in a browsing context?
I am writing a js library that helps tracking navigation when user use back/forward browser buttons. The library would record when user is navigated from page B to page A (backwards) or page A to page B(forward). I've achieved the tracking for the pages that use hashes using the 'popstate' event but when user navigate from page A to page B this event doesn't work.
I've looked at pageshow/pagehide events but they fires on simple page loads as well and not just when the 'session history' changes (ie page fetched from history).
What should i be looking at to know "browser has looked into session history to fetch the current page"?
You're going to have to handle the Window's beforeunload event, and also put code on whichever page loading event is appropriate for your use case.
Note that for beforeunload, you don't have time to write something server-side. You'll have to track this in LocalStorage.
There is something weird in your requirements:
You say you are writing a js library, but for this library to work across different documents, for a start, it would at least have to be executed on every documents navigated by the user.
And even if it were the case, there wouldn't be any solid way to do what you want.
Browsers' behavior regarding history navigation vary a lot:
For instance, FF will keep in memory its current state, and will not reload the page per se, but simply reactivate its saved state (i.e you won't even be able to know that the user came back to this page (apart from ugly polling of performance.navigation.type, which despite what MDN says is only absent in Safari).
So all in all, what you want to make is a job for a browser extension, not for a web-library.

How can I get reason of page unloading in javascript's onunload event, in IE?

There may be different reasons of page unloading:
1 User closes the current window.
2 User navigates to another location.
3 Clicks the Back, Forward, Refresh, or Home button.
4 User submits a form, and then browser starts to unload current page and load page with results of form submitting. (Assuming that the current window is the form's target).
5 and so on...
Can I somehow know in onunload handler that the reason of unloading is p.4, i.e. moving to page with results of form submitting?
I could define some flag when submiting form, but this does not solve the problem. Because response (on form submit) from web server takes some time, browser doesn't unload the current page immediately and waits response from server. And during this waiting user may close window or navigate anywhere. And I need to know whether was it indeed moving to results page or something else...?
You could hijack some of those events.
For example for links, you could add an event handler on links that saves their href attribute, performs what you require, then sets window.location to the href you had stored in a variable.
The exact reason of page unload cannot be known in the unload handler. OnUnload event is not a standard and was implemented by IE first.
Different browsers might handle it differently and fire the event for different cases.
msdn reference
mozilla reference
So if you are trying to know the reason of unload in the unload handler, I think you might be out of luck. However as Alex pointed out in his answer, you could probably know about user navigating away from your page by clicking some link on your page by making your click handlers for those links more intelligent.
on unload cant handle its looks like but maybe when load you can handle.
as explained
performance.getEntriesByType("navigation")[0].type
You can check this Link
What is the replacement for performance.navigation.type in angular?

Is there a way in javascript to detect if the unload event is caused via a refresh, the back button, or closing the browser? [duplicate]

This question already has answers here:
Identifying Between Refresh And Close Browser Actions
(13 answers)
Closed 6 years ago.
I am currently looking at the "unload" event of a window to try to determine how the "unload" event was triggered, but am having little success. Is there a way to determine how the javascript event was triggered?
Page Refresh
Back Button (or navigate away from the page)
Closing the Browser
Essentially I need to execute some code only when the browser window is being closed, not refreshed or navigated away from.
Purpose: When a customer does an update of our software, the update will redirect their first Internet request to an offer page. There is a button for a "Do Not Bother" option, but some users will simply close their browser. Upon closing the browser, I need to duplicate the "Do Not Bother" functionality so the user no longer gets redirected to the offer page. Simply attaching to the "unload" event will not work due to the different ways of leaving a page.
No, and if there was it would be browser dependent.
What kind of code are you trying to run when the user closes the page?
Is it to logout the user?
Then the user would not be logged out if the browser crashes or the network connection breaks (and probably not if the computer goes to sleep/hibernation mode).
If it is for logout-purposes you should probably use a timestamp variable at the server that gets updated with every request (or use a ajax-ping), and logout the user if it hasn't been seen for a specified time.
Update: Found this answer here at stackoverflow.
Yes, there is a solution!
I've designed a solution based on onBeforeUnload+onLoad events, HTML5 local storage and client/server communication. See the details on https://stackoverflow.com/a/13916847/698168.
I use a method of doing keyboard "sniffing", in that it looks for keydown's of "F5", "ctrl+r", "alt-f4", "backspace" and others, and if it finds them flowing through the keyboard event queue, it sets boolean variables appropriately to trap that status... then I use a "onbeforeunload" function handler, which tests against those boolean status variables to decide what to do.
You can even shut down various keyboard strokes (like "ctrl+n" or "F1" for instance) by using preventDefault(), bubbles=false and returnValue=false in your keyboard handling.
This stuff is not for the faint of heart, but its certainly doable with some persistence and lots of cross browser testing!

Categories