What JavaScript code do I run when the user closes the tab? - javascript

Summarize the problem
I'm trying to create a macOS tabbed web browser using WKWebView and Swift. Everything works fine except the webpage doesn't know I closed the tab. I want to tell the webpage that I closed the tab
Describe what you've tried
I haven't tried anything because I don't know what to do
Show some code
I've tried doing this
webView.removeFromSuperView()
But the webpage didn't know that I closed the tab
I don't know much javascript so please include code instead of explaining

Javascript scripts use onbeforeunload and onunload events to tap into browser closing.
Since you know the browser is about to close, you can dispatch this event yourself. For example, with beforeunload event:
let script = """
const event = new Event("beforeunload", { cancellable: true });
const cancelled = !window.dispatch(event);
// return back whether the user cancelled
cancelled;
"""
When you need to close the browser, invoke the script:
let webView = WKWebView()
// ... other config
webView.evaluateJavaScript(script, completionHandler: { result, error in
guard let cancelled = result else { return }
if cancelled == 1 {
// ... do whatever
}
})

Related

How to determine whether the user closes browser tab or refreshes the page

I am building a two person game app using vue.js. The app uses vuex for state management and Firestore as the backend server.
If the user leaves the app by either closing the browser tab or navigating away, the games Firestore files need to be deleted. However, if the user refreshes the page, the Firestore files need to remain so that the reload process can repopulate the game.
So I need to determine if the user has refreshed the page as opposed to closing the browser or navigating away.
As shown below, in vue's created lifecycle I setup a "beforeunload" event Listener and also start 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");
},
The getUnloadInitiator function is shown below. This is where I need help. Right now all this function does is console.log 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;
}
Below is the output from my console.logs. They are the same for refreshing the page, closing the browser tab, or navigating away. All 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
===============================
Any help on how to differentiate between refreshing the page, closing the browser tab, or navigating away would be appreciated. There must be away, because the native cancel browser popup I'm using for debug purposes differentiates between fresh and browser tab close.
Thanks
You can use a source of authority as persistence, be it firestore, local storage, or cookies. you are able to get the browser's tab ID with tab.id and compare it to an existing one should one exist.
browser.pageAction.show(tab.id);
Source: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Working_with_the_Tabs_API

Why browser refresh and close event detection is not working for IE and Safari

I need to call logout function on the close of browser window gets close. It's working fine in Chrome not working in IE and Safari.
I have tried the following code:
window.onbeforeunload = function (e) {
// Your logic to prepare for 'Stay on this Page' goes here
var evtobj = window.event ? event : e;
if (evtobj == e) {
//firefox
if (!evtobj.clientY) {
//server call
}
}
else {
//IE
if (evtobj.clientY < 0) {
//server call
}
}
//return "Please click 'Stay on this Page' and we will give you candy";
};
I have tried a few other ways but they didn't work. Please advise.
There is something wrong in your design, you SHOULDN'T rely on a client-side hook to perform logout. There are one billion of reasons why that event could not be executed. Just limit the onbeforeunload event to execute informational content and not critical actions.
By the way:
Don't return in your beforeunload event! This creates some issue in IE
Use window.sessionStorage to make some data last until the user closes the tab
Use session cookies to store your user's sensitive data like as tokens, and check if a user is logged on the server, and not on the client

How to detect the printed status or canceled status in web browser using javascript?

I am just detecting the printed status in web browser.
As you can see , browser support the status as cancel or print button.
For seeing if user clicked cancel, print button, I am just using javascript.
but I had not got good result for that.
Are there good way to detect the status ?
window.print() doesn't return any value.
I don't think there's a way to know if the user clicked Save or Cancel. It's more of your operating system's job to watch what's going on in there. There're, however, two event handlers
window.onbeforeprint and
window.onafterprint.
Code Snippet
window.onbeforeprint = function() {
console.log('This will be called before the user prints.');
};
window.onafterprint = function() {
console.log('This will be called after the user prints');
};
Take a look here

How to determine if google auth2.signIn() window was closed by the user?

Im implementing auth using this and am currently showing a loading icon in React when a user clicks the button to sign in and the auth2 account selection/login window shows.
However if a user closes the window, there doesnt seem to be any event fired i.e the signIn() function which returns a promise never resolves, I would have thought google would return an error for this promise if the window is closed. As a result there is no way for me to stop showing the loader icon and reshow the login menu.
I was wondering if anyone had a solution for this?
I try to modifiy my code that call Google OAuth 2.0 window.
You only have to add extra AJAX method that cover what is Google OAuth error result.
gapi.auth2.getAuthInstance().signIn()
Change it to this one,
gapi.auth2.getAuthInstance().signIn().then(function(response){
//If Google OAuth 2 works fine
console.log(response);
}, function(error){
//If Google OAuth 2 occured error
console.log(error);
if(error.error === 'popup_closed_by_user'){
alert('Oh Dude, Why you close authentication user window...!');
}
});
That's it...
For more detail about Google OAuth 2.0 information, you can visit this link.
https://developers.google.com/api-client-library/javascript/samples/samples#authorizing-and-making-authorized-requests
Sample code on JavaScript:
https://github.com/google/google-api-javascript-client/blob/master/samples/authSample.html
Although the API provides a mechanism for detecting when the user clicks the Deny button, there is not a built-in way for detecting that the user abruptly closed the popup window (or exited their web browser, shut down their computer, and so on). The Deny condition is provided in case you want to re-prompt the user with reduced scopes (e.g. you requested "email" but only need profile and will let the user proceed without giving you their email).
If the response from the sign-in callback contains the error, access_denied, it indicates the user clicked the deny button:
function onSignInCallback(authResult) {
if (authResult['error'] && authResult['error'] == 'access_denied') {
// User explicitly denied this application's requested scopes
}
}
You should be able to implement sign-in without detecting whether the window was closed; this is demonstrated in virtually all of the Google+ sample apps. In short, you should avoid using a spinner as you're doing and instead should hide authenticated UI until the user has successfully signed in.
It's not recommended you do this, but to implement detection of the pop-up closing, you could do something like override the global window.open call, then detect in window.unload or poll whether the window was closed without the user authenticating:
var lastOpenedWindow = undefined;
window.open = function (open) {
return function (url, name, features) {
// set name if missing here
name = name || "default_window_name";
lastOpenedWindow = open.call(window, url, name, features);
return lastOpenedWindow;
};
}(window.open);
var intervalHandle = undefined;
function detectClose() {
intervalHandle = setInterval(function(){
if (lastOpenedWindow && lastOpenedWindow.closed) {
// TODO: check user was !authenticated
console.log("Why did the window close without auth?");
window.clearInterval(intervalHandle);
}
}, 500);
}
Note that as I've implemented it, this mechanism is unreliable and subject to race conditions.

javascript open popup before closing the current tab

I want to open a popup when the user closes the last tab of the current site. The problems I have is that
when the browser prompts the user (onbeforeunload returning a non null value), then the popup is blocked by the browser (see case 1 below)
when the browser does not prompt anything to the user (onbeforeunload not returning anything), then the popup is not opened at all and seemed to be totally ignored by the browser (why is that?) (see case 2 below)
Case 1: prompt and popup blocked (code from this answer)
window.onbeforeunload = function (e) {
e = e || window.event;
window.open('http://localhost', '_blank');
// For IE and Firefox prior to version 4
if (e) {
e.returnValue = 'Sure?';
}
// For Safari
return 'Sure?';
};
Case 2: no prompt, no popup, page closing "normally"
window.onbeforeunload = function (e) {
e = e || window.event;
window.open('http://localhost', '_blank');
};
From the specification:
An algorithm is allowed to show a popup if any of the following conditions is true
The task in which the algorithm is running is currently processing an activation behavior whose click event was trusted.
The window closing is not a click event.
The task in which the algorithm is running is currently running the event listener for a trusted event whose type is in the following list:
unload is not in that list.
The task in which the algorithm is running was queued by an algorithm that was allowed to show a popup, and the chain of such algorithms started within a user-agent defined timeframe.
For example, if a user clicked a button, it might be acceptable for a popup to result from that after 4 seconds, but it would likely not be acceptable for a popup to result from that after 4 hours.
Again, no. The task wasn't queued.
It is not possible to open a popup in response to a user trying to leave your site. It would enable too many harmful behaviours (click on this advert, quit, popup, you must click on this advert, loop).
Here's my code:
var popWindow = true;
window.onbeforeunload = function() {
if(popWindow == true) {
popWindow = false;
return "Sure?";
}
}
http://jsfiddle.net/anam/su8dznoa/

Categories

Resources