How to prevent closing browser window?
JavascriptBrowserWindowOnbeforeunloadJavascript Problem Overview
I tried the following code to get an alert upon closing a browser window:
window.onbeforeunload = confirmExit;
function confirmExit() {
return "You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?";
}
It works, but if the page contains one hyperlink, clicking on that hyperlink raises the same alert. I need to show the alert only when I close the browser window and not upon clicking hyperlinks.
Javascript Solutions
Solution 1 - Javascript
Another implementation is the following you can find it in this webpage: http://ujap.de/index.php/view/JavascriptCloseHook
<html>
<head>
<script type="text/javascript">
var hook = true;
window.onbeforeunload = function() {
if (hook) {
return "Did you save your stuff?"
}
}
function unhook() {
hook=false;
}
</script>
</head>
<body>
<!-- this will ask for confirmation: -->
<a href="http://google.com">external link</a>
<!-- this will go without asking: -->
<a href="anotherPage.html" onClick="unhook()">internal link, un-hooked</a>
</body>
</html>
What it does is you use a variable as a flag.
Solution 2 - Javascript
Keep your code as is and use jQuery to handle links:
$(function () {
$("a").click(function {
window.onbeforeunload = null;
});
});
Solution 3 - Javascript
You can detect hyperlinks clicks, but you can't determine whether user:
- Attempted to refresh page.
- Attempted to close browser tab.
- Attempted to close browser window.
- Inputted another URL in the URL bar and hit enter.
All these actions generate beforeunload
event on window
, without any more exact information about the event.
In order to display confirmation dialog when doing above actions, and not display it when a hyperlink was clicked, follow these steps:
- Assign
beforeunload
event listener towindow
, which returns confirmation text as a string, unless a specific variable (flag) is set totrue
. - Assign
click
event todocument
. Check ifa
element has been clicked (event.target.tagName
). If yes, set flag totrue
.
You should also handle form submissions by assigning a submit
event listener to document
.
Your code could look like this:
let disableConfirmation = false;
window.addEventListener('beforeunload', event => {
const confirmationText = 'Are you sure?';
if (!disableConfirmation) {
event.returnValue = confirmationText; // Gecko, Trident, Chrome 34+
return confirmationText; // Gecko, WebKit, Chrome <34
} else {
// Set flag back to false, just in case
// user stops loading page after clicking a link.
disableConfirmation = false;
}
});
document.addEventListener('click', event => {
if (event.target.tagName.toLowerCase() === 'a') {
disableConfirmation = true;
}
});
document.addEventListener('submit', event => {
disableConfirmation = true;
});
<p><a href="https://stacksnippets.net/">google.com</a></p>
<form action="https://stacksnippets.net/"><button type="submit">Submit</button></form>
<p>Try clicking the link or the submit button. The confirmation dialog won't be displayed.</p>
<p>Try reloading the frame (right click -> "Reload frame" in Chrome). You will see a confirmation dialog.</p>
Note that in some browsers you have to use event.returnValue
in beforeunload
listener, and in others you use return
statement.
See also beforeunload
event docs.
Solution 4 - Javascript
I have added an additional code that will to handle further process of if window is closed
let disableConfirmation = false;
window.addEventListener('beforeunload', event => {
const confirmationText = 'Are you sure?';
if (!disableConfirmation) {
event.returnValue = confirmationText; // Gecko, Trident, Chrome 34+
return confirmationText; // Gecko, WebKit, Chrome <34
} else {
// Set flag back to false, just in case
// user stops loading page after clicking a link.
disableConfirmation = false;
}
});
After Confimation if you want to send any ajax request and you have used jquery
$(window).on('unload', function() {
// async: false will make the AJAX synchronous in case you're using jQuery
axios
.get('ajax_url')
.then(response => {});
});
And if no jquery is used you can use navigator, it require navigator library
navigator.sendBeacon(url, data);
you can download this library from here : https://github.com/miguelmota/Navigator.sendBeacon