Respuesta corta e incorrecta:
Puede hacer esto manejando el beforeunloadevento y devolviendo una cadena no nula :
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.
});
El problema con este enfoque es que enviar un formulario también está activando el evento de descarga . Esto se soluciona fácilmente agregando una marca que está enviando un formulario:
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.
});
};
Luego llamando al setter al enviar:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
Pero sigue leyendo ...
Respuesta larga y correcta:
Tampoco desea mostrar este mensaje cuando el usuario no ha cambiado nada en sus formularios . Una solución es usar el beforeunloadevento en combinación con una bandera "sucia", que solo activa el aviso si es realmente relevante.
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.
});
};
Ahora para implementar el isDirtymétodo, hay varios enfoques.
Puede usar jQuery y la serialización de formularios , pero este enfoque tiene algunos defectos. Primero, tiene que modificar el código para que funcione en cualquier forma ( $("form").each()lo hará), pero el mayor problema es que jQuery serialize()solo funcionará en elementos con nombre y sin discapacidad, por lo que cambiar cualquier elemento con o sin nombre no activará el indicador sucio. Hay soluciones alternativas para eso , como hacer que los controles sean de solo lectura en lugar de habilitar, serializar y luego deshabilitar los controles nuevamente.
Entonces los eventos parecen el camino a seguir. Puedes intentar escuchar las pulsaciones de teclas . Este evento tiene algunos problemas:
- No se activará en casillas de verificación, botones de radio u otros elementos que se están alterando a través de la entrada del mouse.
- Se activará para pulsaciones de teclas irrelevantes como la Ctrltecla.
- No se activará en valores establecidos a través del código JavaScript.
- No se activará al cortar o pegar texto a través de menús contextuales.
- No funcionará para entradas virtuales como fechadores o embellecedores de casillas de verificación / botones de radio que guardan su valor en una entrada oculta a través de JavaScript.
El changeevento también no se activa en los valores establecidos de código JavaScript , por lo que también no funcionará para entradas virtuales.
Vincular el inputevento a todos los inputs (y textareas y selects) en su página no funcionará en navegadores antiguos y, como todas las soluciones de manejo de eventos mencionadas anteriormente, no admite deshacer. Cuando un usuario cambia un cuadro de texto y luego lo deshace, o marca y desmarca una casilla de verificación, el formulario aún se considera sucio.
Y cuando desee implementar más comportamiento, como ignorar ciertos elementos, tendrá aún más trabajo por hacer.
No reinventes la rueda:
Entonces, antes de pensar en implementar esas soluciones y todas las soluciones alternativas necesarias, tenga en cuenta que está reinventando la rueda y que es probable que tenga problemas que otros ya han resuelto para usted.
Si su aplicación ya usa jQuery, también puede usar código probado y mantenido en lugar de crear el suyo propio, y usar una biblioteca de terceros para todo esto. jQuery's ¿Estás seguro? El complemento funciona muy bien, vea su página de demostración . Es tan simple como esto:
<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>
Mensajes personalizados no admitidos en todas partes
Tenga en cuenta que Firefox 4 no admite mensajes personalizados en este cuadro de diálogo. A partir de abril de 2016, Chrome 51 se está implementando en el que también se eliminan los mensajes personalizados .
Existen otras alternativas en otras partes de este sitio, pero creo que un diálogo como este es lo suficientemente claro:
¿Quieres salir de este sitio?
Los cambios que realizó no se pueden guardar.
Leave Stay