I used synchronous AJAX (JAX) request and run handler for events onUnload or onBeforeUnload once for the respective browser. This solution has a single and almost cross-browser behavior.
Example (on jsfiddle):
$(document).ready(function() {
var form = $('form');
var textareas = $('textarea');
function array_compare(a_0, a_1) {
if(a_0.length != a_1.length)
return false;
for(i = 0; i < a_0.length; i++)
if(a_0[i] != a_1[i])
return false;
return true;
}
var flag = false; // flag to control the execution of the unloadHandler() once
var a_open = []; // array with data before unload
$('textarea').each(function(index) {
a_open.push($(this).val());
});
function unloadHandler() {
if (flag)
return;
var a_close = []; // array with data during unload
$('textarea').each(function(index) {
a_close.push($(this).val());
});
if (!array_compare(a_open, a_close)) {
if (confirm('You changed the data, but not saved them. Save?')) {
$.ajax({
type: 'POST',
url: '/echo/json/',
async: false,
data: form.serialize()/* {
json: JSON.stringify({
text: 'My test text.'
}),
delay: 3
} */,
success: function(data) {
if (data) {
console.log(data);
alert('All data is saved!');
}
}
});
}
}
flag = true;
}
// For FireFox, Chrome
$(window).on('beforeunload', function () {
unloadHandler();
});
// For Opera, Konqueror
$(window).unload(function() {
unloadHandler();
});
// Without message when pressed submit button
$('form').submit(function() {
$(window).off('beforeunload');
$(window).off('unload');
});
});