Strategies for distinguishing between when a user closes a browser tab or refreshes the page

I'm currently in the process of developing a multiplayer game app using vue.js. For state management, I've opted to utilize vuex and for the backend server, I have integrated Firestore.

A crucial aspect of the app is handling user interactions when they leave the platform. Specifically, if a user closes the browser tab or navigates away from the page, the game data stored in Firestore needs to be deleted. However, if the user simply refreshes the page, the Firestore files should remain intact to facilitate a seamless reload process.

Therefore, there is a need to distinguish between a page refresh and other forms of exiting the app.

In the code snippet below, you can observe that during vue's created lifecycle, I establish a "beforeunload" event listener and initialize my Firestore listeners:

created() {
    // This window event listener fires when the user
    // navigates away from or closes the browser window
    window.addEventListener("beforeunload", (event) => {
        const isByRefresh = getUnloadInitiator();
        if (!isByRefresh) {
            this.stopFirestoreListeners("beforeunload");
        }
        // Cancel the event. This allows the user to cancel via popup. (for debug purposes)
        event.preventDefault();
        event.returnValue = "";

        // the absence of a returnValue property on the event
        // guarantees the browser unload happens
        // delete event["returnValue"];
    });

    this.startFirestoreListeners("created");

},

Highlighted below is the getUnloadInitiator function that requires assistance. Currently, the function mainly logs various performance values:

function getUnloadInitiator() {
// check for feature support before continuing
if (performance.mark === undefined) {
    console.log("performance.mark NOT supported");
    return false;
}
console.log("===============================");
// Yes I know that performance.navigation is depreciated.
const nav = performance.navigation;
console.log("nav=", nav);
console.log("===============================");

// Use getEntriesByType() to just get the "navigation" events
var perfEntries = performance.getEntriesByType("navigation");
for (var i = 0; i < perfEntries.length; i++) {
    var p = perfEntries[i];
    console.log("= Navigation entry[" + i + "]=", p);
    // other properties
    console.log("type = " + p.type);
}
console.log("===============================");

performance.mark("beginLoop");
const entries = performance.getEntries({
    name: "beginLoop",
    entryType: "mark",
});
const firstEntry = entries[0];
console.log("firstEntry.type=", firstEntry.type);

console.log("===============================");

//TODO: Determine how unload was initiated
return true;
}

The following output displays the results from the console.logs. Surprisingly, all scenarios—refreshing the page, closing the browser tab, or navigating away—show "reload" as the navigation type:

===============================
nav= PerformanceNavigation {type: 1, redirectCount: 0}
===============================
= Navigation entry[0]= PerformanceNavigationTiming {unloadEventStart: 25.399999976158142, unloadEventEnd: 25.69999998807907, domInteractive: 633, domContentLoadedEventStart: 633, domContentLoadedEventEnd: 633, ...}
type = reload
===============================
firstEntry.type= reload
===============================

If anyone could provide insights on differentiating between these actions (refreshing, closing tab, or navigating away), it would be greatly appreciated. The ability to determine such distinctions is evident through the debug pop-up used for canceling browser operations.

Thank you!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to efficiently clear the Express session for all users without the need to restart the application?

During my development of REST services using the nodejs express framework, I encountered an issue with storing user-specific data in sessions. I utilized the user's ID as a key to identify the user's data. The following code snippet demonstrates ...

Using Jquery Ajax to Develop Laravel Dropdown Selection with Cascading Feature

I have been working with Laravel 5.6 and encountered an issue with my dropdown selection. Although I selected a province from the dropdown menu, the city menu did not display the corresponding cities. Below is the controller code that I am using: public f ...

How can you extract elements from a JSON array into separate variables based on a specific property value within each element?

In the following JSON array, each item has a category property that determines its grouping. I need to split this array into separate JSON arrays based on the category property of each item. The goal is to extract all items with the category set to person ...

Tips for sharing the scope using module.exports

Within handler.js, I have exported 2 functions: one for initialize() and the other for handle(). The initialize function is used to dynamically load the handler based on the application settings. I have a shared variable called var handler outside the modu ...

Tips on targeting a click event on a Vue input field

How can I make an input field focused when a button is clicked? <div class="form-group" v-for="(file, i) in registerData.requiredDocuments" :key="`file-${i}`"> <label for="npwp" class="text-muted"> {{file.name}} </label> <input ...

Issue encountered while parsing JSON file using AngularJS

Having some trouble reading a json file in AngularJS using $http.get and encountering errors in the browser console. Check out my Plunker example: http://plnkr.co/edit/SDRpu1MmrTPpgpdb6Kyk?p=preview Below is the code snippet: Javascript:- var jayApp = ...

I'm encountering a type error every time I attempt to render an EJS page. Could someone please take a look and help me troubleshoot?

Below is the index.js code: CODE HERE const express = require('express'); const app = express(); const path = require('path'); app.use(express.urlencoded({ extended: true })) // for parsing application/x-www-form-urlencoded app.use(ex ...

Is it possible to utilize Vue-I18n without the need for a build process?

If I want to use Vue2 without any build step, is it possible to incorporate Vue-I18n in the same way? <!doctype html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_ema ...

Vue email validation is failing to return a valid email address

I'm relatively new to Vue and have implemented email validation using the reg expression in my Vue script data for this project. By utilizing console.log(this.reg.test(this.email)) and observing the output while users input their email, the validation ...

Elements in Motion

Working on a parallax effect, I've managed to assign unique scroll speeds to (almost) every element. Moreover, these elements are programmed not to activate their scroll speed until they enter the viewport. Below is the JavaScript code for trigger co ...

Arranging JavaScript object by object properties (name)

Can anyone assist me with my training? I am currently learning JavaScript (Js) and TypeScript (Ts) by working with an external public API. After successfully fetching and displaying my data, I now want to implement sorting functionality. My goal is to sor ...

Prevent form submission when processing is in progress

I've got this code working perfectly: $(function() { $("input,textarea").jqBootstrapValidation({ preventSubmit: true, submitError: function($form, event, errors) { // additional error messages or events ...

showing information on webpage 2 received via query parameters from webpage 1

Hello, I am trying to input text into a textarea and then send the data through a query string to another webpage. My goal is to display the data on the second webpage. I have written the following code, but it doesn't seem to be working. I've ch ...

Sending asynchronous requests to handle data within various functions based on different links

I'm currently facing a major roadblock when it comes to resolving my issues with callbacks. I've gone through resources like How to return value from an asynchronous callback function? and How to return the response from an Ajax call?, among seve ...

Creating impenetrable div elements with JavaScript or jQuery

I'm currently working on creating solid blocks using DIVs positioned side by side both horizontally and vertically. I've successfully achieved this when the divs have equal heights. However, an issue arises when a div has larger dimensions; it en ...

Printing without sufficient paper will result in an incomplete printout

https://i.stack.imgur.com/jNlRr.jpg I am facing an issue with printing the last column "Potensi". The text in this column is not fully printed. How can I resolve this problem? I am using PHP. Thank you ...

Hey there! I'm currently facing some difficulties with storing form input data into a nested json file

I have developed a Next.js application with a form component structured as follows: components/Form.js import { useState } from 'react' import { useRouter } from 'next/router' import { mutate } from 'swr' const Form = ({ for ...

The React setState function isn't updating the state as expected when used within the useEffect hook

I'm new to using hooks and I'm facing an issue with setState when trying to update data received from an API. Despite logging the response data successfully, it seems that the state does not update as expected. My useEffect function is set to run ...

Replace the image source with a list of images

I am looking to create a dynamic image list using either an array or an HTML list. When I hover over an image, it should change one by one with a fade or slide effect, and revert back to the default images when I hover out. Question 1: What type of list s ...