How to prevent closing browser window?
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.
Keep your code as is and use jQuery to handle links:
$(function () {
$("a").click(function {
window.onbeforeunload = null;
});
});
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.
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