Respuesta corta e incorrecta:
Puede hacer esto manejando el beforeunload
evento 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 beforeunload
evento 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 isDirty
mé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 change
evento 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 input
evento a todos los input
s (y textarea
s y select
s) 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