I often accidentally close my Chrome browser and have to reopen and reload all the tabs that I'd been working on. Since Chrome does not a have built in confirm before closing mechanism, I wrote a simple page to ask for confirmation before closing. I leave that page open among my other tabs.
<!DOCTYPE html>
<html>
<body>
<p>This page is to prevent accidental closing of Chrome.</p>
<script language="JavaScript">
window.onbeforeunload = function () {
return "Are you sure?";
};
</script>
</body>
</html>
Recently I updated my Chrome browser from version 56 to 60. Now the code doesn't seem to work as it no longer asks for confirmation before closing. I tried many different variations from the internet but none seem to work.
Note: I am very new to web development.
According to the MDN docs :
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.
So, I think your function is not guaranteed to run, especially because
Chrome 60 explicitly has that first behaviour. From the notes:
From Chrome 60 onward, the beforeunload dialog will only appear if the frame attempting to display it has received a user gesture or user interaction (or if any embedded frame has received such a gesture).
So if you want to continue using this approach, you may need to interact with the page at some point in your session.
Alternatively, to open all the tabs you had open when you restart Chrome, try pressing Ctrl-Shift-T.
Related
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.
Given a webpage that sets the beforeunload event handler in the Safari browser and the development console is closed, the beforeunload handler cannot always prevent navigation away from the webpage. When the development console is open, the handler almost always can prevent navigation away from the page.
This may be reproduced in two ways.
Reproducible Method 1
Using a Safari Browser (Version 12.0.3 (13606.4.5.3.1)) visit the following index.html:
<!doctype html>
<html lang="en">
<body>
<script type="text/javascript">
window.onbeforeunload = (evt) => { evt.preventDefault(); evt.returnValue = false; return true; };
</script>
<p>hello, world!</p>
</body>
</html>
then, open the development console, select the navigation bar, type www.ibm.com and hit return. An alert will appear prompting the user to "Stay" or "Leave".
Close the console, retry the navigation, a prompt may or may not appear. If it does appear and is not clicked within 2-5 seconds ("Stay"), the new page will be visited although the prompt will remain. Clicking on the prompt has no apparent affect after that.
Reproducible Method 2
Using a Safari browser begin to answer a stackoverflow question. Open the development console, then using the navigation bar attempt to visit another site. An alert should appear guarding against loss of form data. Then, close the development console and re-attempt the navigation. This time, the navigation should go through and no alert will be displayed or, if too long before selecting "Stay", navigation will continue.
Discussion
Can anyone else reproduce this?
Advice on whether I should file a bug against Safari or Webkit is welcome.
I've tested Method 1 on Firefox and did not see the same behavior - beforeunload acted mostly as expected.
Have I failed to conjure the onbeforeunload function in just the correct way?
I first saw this using Angular (with rxjs), however, as I've been able to reproduce it with straight HTML and in another website, this has nothing to do with Angular.
EDIT (2019-06-18)
Marked as possible duplicate of this question. It is not because that question explores a bug due to back button and bf history caching in Safari. This problem occurs without pressing the Back Button. If it is related somehow to the browser cache mentioned in the associated bug, someone will have to explain that to me, as I cannot see any obvious connection.
I have a problem when I am trying to check the source of an interesting page which keeps refreshing automatically every 3-5 seconds (presumably due to some js script) which resets my Inspect Element Inspector window every time the page is refreshed.
Is there any other way other to stop that page from refreshing or perhaps the Inspector window from resetting itself other than turning on NoScript to stop the page from refreshing automatically?
Usually I just open DevTools, switch to the appropriate panel if necessary, and hit pause.
Opening DevTools: Via menus, or by press F12, Ctrl+Shift+I, or Cmd+Shift+I depending on browser and OS.
Switching panels: Pick the panel from the tabs at the top of DevTools. It'll be called "Debugger" (Firefox, IE) or "Sources" (Chrome) or similar.
Pausing: In the Debugger/Sources panel, click the pause button (usually looks like the pause button on a television remote control, ||) or press the keyboard equivalent. Keyboard equivalents are
Firefox & Chrome: F8
IE: Ctrl+Shift+B
(Updated 2020-03-30)
In Firefox 74 this option is in Options -> Privacy & Security -> Permissions
(Original reply)
Firefox has the option to prevent refresh natively, the option is in Advanced->General->Warn me when websites try to redirect or reload the page
The most popular solution for this problem is to trap the beforeunload event. The browser will ask the user for confirmation to leave the page. The code, in its simplest form, looks like this:
window.onbeforeunload = function() { return true }
You can enter this code in console. Alternately, you can simply paste the following URL in the browser address bar (console not required). You can even bookmark it.
javascript:window.onbeforeunload = function() { return true }
Be advised that modern browsers might chop off the javascript: part when you paste it inside the address bar; make sure you type it back.
To determine the cause of redirect in Firefox, try the following:
Open Web Developer Tools (CTRL + SHIFT + I), open "Toolbox Options" and check the "Enable persistent logs" option. This makes the logs persist across page loads (logs are cleared otherwise).
Now switch to "Network Monitor" tab.
Open the URL and let it refresh.
Inside the Network Monitor > Cause column you will find out why the page reloads.
The cause column is pretty ambiguous (Chrome does a much better job). However, if JavaScript was used to trigger page (re)load then it at least shows you the filename and line number of that script.
When the page is still loading, you can press the Esc key. While the page is still white, press it. When you stop the page from loading at this point, this usually stops all the auto loaded javascript. Any scripts that run on actions are usually not effected. Each page is different, try different timings.
When I use a site called NovelUpdates there is javascript that can make certain elements hidden, and when I press Esc on page load all the elements that would be hidden after page load are visible. Then when I click a button that would execute javascript that operates with no problems. NoScript isn't going to solve your issue I believe.
Another example of this are those websites with annoying boxes that pop out after 10 seconds that says you aren't a member and can't view any more of this site without logging in, like some news article websites.
What you could do is use the command exit(), which is the equivalent to die in php and simply stops the script.
If you don't know what's causing it and you don't want to look for the "bad boy", then you might as well stop the entire script at the very bottom of the page.
I need a confirmation pop up on browser close. I amm using onbeforeunload event but not working in Firefox also the pop up comes whenever the page refreshed which I want to restrict.
window.onbeforeunload = DetectBrowserExit;
function DetectBrowserExit() {
return 'Are you sure to exit';`enter code here`
}
Not all browsers support this feature and with time browsers minimized their support (for example removed custom text support).
Reason is that it is used by spam like websites that prevent you from navigating out.
you can see full details here:
https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload
Checkout also the Browser compatibility section in that page.
I would definitely suggest NOT to rely on that event and come up with alternatives that fit your website more.
specifically about firefox, see this explanation from the link I shared above:
Note also that various mobile browsers ignore the result of the event (that is, they do not ask the user for confirmation). Firefox has a hidden preference in about:config to do the same. In essence this means the user always confirms that the document may be unloaded.
UPDATE
So after reading both of your answers I realize there is no reliable way to determine when a browser window is closed. Originally I was planning to use this to unlock a record in the database when the page is closed. Basically when the user loads the page the record it's accessing locks and then unlocks when the page is closed. Any suggestions on how to do this differently/better? I was thinking about just posting a notice on the page that they have to use a close button to close the form rather than the X, and if they do close using the X, the record stays locked for say 5 minutes until they can access it again.
This code is very simple because I was just testing it out. Basically when I run this page in IE and Chrome, the alert fires just fine. When I run it in Firefox, in only a single tab, and close the entire browser, the alert never fires. However, if I have multiple tabs and open the page as a new tab and then close it using the X on the tab, the alert fires. Does anyone know what Firefox is doing back there?
Any help is appreciated, because having to have multiple tabs open just to get onunload to fire is pretty undesirable.
<html>
<head runat="server">
<title></title>
<script type="text/javascript">
window.onunload = function() {
alert("unload event detected!");
}
</script>
</head>
<body>
</body>
</html>
You can't count on onunload handlers firing at all (it's not just Firefox). onbeforeunload handlers are slightly more reliable, but only slightly.
Update Responding to your follow-up question: If you have to use a lock, then yes, I would definitely use a server-side timeout (you have no other choice; if the user's workstation blue-screens, for instance, you want that record unlocked at some point). You probably want to reset the timeout any time you see activity from the user (you could use an ajax ping while the page is open) and, as you said, give the user a means of explicitly releasing the record. How long that timeout should be is up to you, but if you used the ajax ping mechanism, no reason it would even need to be five minutes — you could do a one-minute timeout and a 30-second ajax ping, or even a 30-second timeout and a 15-second ping, whatever. Depends on what kind of load you want to put on the server.
Firefox closes immediately after you click the X to close the browser. For some reason it 'forgets' to call the onunload event.