How to distinguish between refresh (by F5/refresh button) and close browser?

Viewed 4816

I have requirement to handle events on browser like back, refresh and close on cross browser. The problem is my customer want a different logic for each of those events. For back button, this solution is quite fine:

but Now it's hard to distinguish between refresh and close, all solutions i found is about using of "beforeunload" event:

For refreshing by F5, i can catch event on keyboard, but when user press refresh button on browser, i can't. If i use "beforeunload", it is the same with close browser event.

I also found a workaround solution:

but unfortunately, what i want to do is showing message before page unload (show when browser is close but not when refreshing)

Does anyone know a solution for it (cross browser)

Thanks

2 Answers
tabOrBrowserStillAliveInterval;

constructor() {
  // do some action if the browser or last opened tab was closed (in 15sec after closing)
  if (this.wasBrowserOrTabClosed()) {
    // do some action
  }

  // every 15sec update browserOrTabActiveTimestamp property with new timestamp
  this.setBrowserOrTabActiveTimestamp(new Date());
  this.tabOrBrowserStillAliveInterval = setInterval(() => {
    this.setBrowserOrTabActiveTimestamp(new Date());
  }, 15000);
}

setBrowserOrTabActiveTimestamp(timeStamp: Date) {
  localStorage.setItem(
    'browserOrTabActiveSessionTimestamp',
    `${timeStamp.getTime()}`
  );
}

wasBrowserOrTabClosed(): boolean {
  const value = localStorage.getItem('browserOrTabActiveSessionTimestamp');

  const lastTrackedTimeStampWhenAppWasAlive = value
    ? new Date(Number(value))
    : null;
  const currentTimestamp = new Date();
  const differenceInSec = moment(currentTimestamp).diff(
    moment(lastTrackedTimeStampWhenAppWasAlive),
    'seconds'
  );

  // if difference between current timestamp and last tracked timestamp when app was alive
  // is more than 15sec (if user close browser or all opened *your app* tabs more than 15sec ago)
  return !!lastTrackedTimeStampWhenAppWasAlive && differenceInSec > 15;
}

How it works: If the user closes the browser or closes all opened your app tabs then after a 15sec timeout - an action that you expect will be triggered.

  • it works with multiple windows open
  • no additional load on the server
  • no problem with F5 / refresh

Browser limitations are the reason why we need 15sec timeout before logout. Since browsers cannot distinguish such cases: browser close, close of a tab, and tab refresh. All these actions are considered by the browser as the same action. So 15sec timeout is like a workaround to catch only the browser close or close of all the opened your app tabs (and skip refresh/F5).

Related