How to call a function before leaving page with Javascript
You can always call your function before leaving the page.
function myfun(){
// Write your business logic here
console.log('hello');
}
onbeforeunload:
window.onbeforeunload = function(){
myfun();
return 'Are you sure you want to leave?';
};
Or with jQuery:
$(window).bind('beforeunload', function(){
myfun();
return 'Are you sure you want to leave?';
});
This will just ask the user if they want to leave the page or not, you cannot redirect them if they select to stay on the page. If they select to leave, the browser will go where they told it to go.
You can use onunload to do stuff before the page is unloaded, but you cannot redirect from there (Chrome 14+ blocks alerts inside onunload):
window.onunload = function() {
myfun();
alert('Bye.');
}
Or with jQuery:
$(window).unload(function(){
myfun();
alert('Bye.');
});
Javascript, do something before leaving page
From the documentation:
When this event returns (or sets the returnValue property to) a value other than null or undefined, the user is prompted to confirm the page unload.
https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload
So you should not do a return true;
at the end of this function.
Warn user before leaving web page with unsaved changes
Short, wrong answer:
You can do this by handling the beforeunload
event and returning a non-null string:
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
The problem with this approach is that submitting a form is also firing the unload event. This is fixed easily by adding the a flag that you're submitting a form:
var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
Then calling the setter when submitting:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
But read on...
Long, correct answer:
You also don't want to show this message when the user hasn't changed anything on your forms. One solution is to use the beforeunload
event in combination with a "dirty" flag, which only triggers the prompt if it's really relevant.
var isDirty = function() { return false; }
window.onload = function() {
window.addEventListener("beforeunload", function (e) {
if (formSubmitting || !isDirty()) {
return undefined;
}
var confirmationMessage = 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.';
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});
};
Now to implement the isDirty
method, there are various approaches.
You can use jQuery and form serialization, but this approach has some flaws. First you have to alter the code to work on any form ($("form").each()
will do), but the greatest problem is that jQuery's serialize()
will only work on named, non-disabled elements, so changing any disabled or unnamed element will not trigger the dirty flag. There are workarounds for that, like making controls readonly instead of enabling, serializing and then disabling the controls again.
So events seem the way to go. You can try listening for keypresses. This event has a few issues:
- Won't trigger on checkboxes, radio buttons, or other elements that are being altered through mouse input.
- Will trigger for irrelevant keypresses like the Ctrl key.
- Won't trigger on values set through JavaScript code.
- Won't trigger on cutting or pasting text through context menus.
- Won't work for virtual inputs like datepickers or checkbox/radiobutton beautifiers which save their value in a hidden input through JavaScript.
The change
event also doesn't trigger on values set from JavaScript code, so also won't work for virtual inputs.
Binding the input
event to all input
s (and textarea
s and select
s) on your page won't work on older browsers and, like all event handling solutions mentioned above, doesn't support undo. When a user changes a textbox and then undoes that, or checks and unchecks a checkbox, the form is still considered dirty.
And when you want to implement more behavior, like ignoring certain elements, you'll have even more work to do.
Don't reinvent the wheel:
So before you think about implementing those solutions and all required workarounds, realize you're reinventing the wheel and you're prone to running into problems others have already solved for you.
If your application already uses jQuery, you may as well use tested, maintained code instead of rolling your own, and use a third-party library for all of this.
jquery.dirty (suggested by @troseman in the comments) provides functions for properly detecting whether a form has been changed or not, and preventing the user from leaving the page while displaying a prompt. It also has other useful functions like resetting the form, and setting the current state of the form as the "clean" state. Example usage:
$("#myForm").dirty({preventLeaving: true});
An older, currently abandoned project, is jQuery's Are You Sure? plugin, which also works great; see their demo page. Example usage:
<script src="jquery.are-you-sure.js"></script>
<script>
$(function() {
$('#myForm').areYouSure(
{
message: 'It looks like you have been editing something. '
+ 'If you leave before saving, your changes will be lost.'
}
);
});
</script>
Custom messages not supported everywhere
Do note that since 2011 already, Firefox 4 didn't support custom messages in this dialog. As of april 2016, Chrome 51 is being rolled out in which custom messages are also being removed.
Some alternatives exist elsewhere on this site, but I think a dialog like this is clear enough:
Do you want to leave this site?
Changes you made may not be saved.
Leave Stay
Dialog action before leaving a page
Hope this will help you
jQuery(window).bind('beforeunload',function(){
var Ans = confirm("Are you sure you leave this page!");
if(Ans==true){
return true;
}else{
return false;
}
});
How to warn user before leaving page but not on redirect
Because you may want the event bound in some circumstances but not others within the same window
, you'll have to not only add the event handler to the window
, but you'll have to remove it as well (under the right circumstance) because even though you are changing the URL of the document
loaded in the window
, you are not changing the window
itself:
function handleBeforeUnload (e) {
e.preventDefault();
e.returnValue = '';
}
//Only warn if user is on a New or Edit page
if(location.href.indexOf("/new") !== -1 || location.href.indexOf("/edit") !== -1 {
window.addEventListener('beforeunload', handleBeforeUnload);
} else {
// Remove the previously registered event handler (if any)
window.removeEventListener('beforeunload', handleBeforeUnload);
}
onbeforeunload confirmation before leaving the page not working
In the docs
According to the specification, to show the confirmation dialog an event handler should call preventDefault() on the event.
So, you should at least do
window.onbeforeunload = function(e){
e.preventDefault();
return 'Are you sure you want to leave?';
};
However the docs also state
To combat unwanted pop-ups, browsers may not display prompts created in beforeunload event handlers unless the page has been interacted with, or may even not display them at all.
So you might be all out of luck with a completely empty page you have not interacted with.
Related Topics
Using "Object.Create" Instead of "New"
Why Does Google Prepend While(1); to Their JSON Responses
How to Get the Scrollbar Position with JavaScript
Convert Base64 String to Arraybuffer
What Do Square Brackets Around a Property Name in an Object Literal Mean
When You Pass 'This' as an Argument
Chrome Desktop Notification Example
How to Detect Pressing Enter on the Keyboard Using Jquery
Declaring Variables Without Var Keyword
Emberjs: How to Load Multiple Models on the Same Route
How to Open a Bootstrap Modal Window Using Jquery
Getting Value of Select (Dropdown) Before Change
How to Synchronize a Sequence of Promises
Why JavaScript Treats a Number as Octal If It Has a Leading Zero