Resposta curta e errada:
Você pode fazer isso manipulando o beforeunload
evento e retornando uma sequência não 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.
});
O problema dessa abordagem é que o envio de um formulário também está disparando o evento descarregar . Isso é corrigido facilmente adicionando o sinalizador a que você está enviando um formulário:
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.
});
};
Em seguida, ligue para o setter ao enviar:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
Mas continue a ler ...
Resposta longa e correta:
Você também não deseja mostrar esta mensagem quando o usuário não alterou nada nos seus formulários . Uma solução é usar o beforeunload
evento em combinação com um sinalizador "sujo", que somente aciona o prompt se for 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.
});
};
Agora, para implementar o isDirty
método, existem várias abordagens.
Você pode usar jQuery e serialização de formulários , mas essa abordagem tem algumas falhas. Primeiro, você precisa alterar o código para funcionar de qualquer forma (o $("form").each()
que funcionará), mas o maior problema é que o jQuery serialize()
funcionará apenas em elementos nomeados e não desativados; portanto, alterar qualquer elemento desativado ou não nomeado não acionará o sinalizador sujo. Existem soluções alternativas para isso , como fazer controles somente leitura em vez de habilitar, serializar e desabilitar os controles novamente.
Então os eventos parecem o caminho a percorrer. Você pode tentar ouvir as teclas pressionadas . Este evento tem alguns problemas:
- Não será acionado em caixas de seleção, botões de opção ou outros elementos que estão sendo alterados através da entrada do mouse.
- Irá acionar pressionamentos de tecla irrelevantes como a Ctrltecla.
- Não acionará valores definidos pelo código JavaScript.
- Não será acionado ao recortar ou colar texto nos menus de contexto.
- Não funcionará para entradas virtuais, como seletores de datas ou embelezadores de caixa de seleção / botão de rádio, que economizam seu valor em uma entrada oculta por meio de JavaScript.
O change
evento também não dispara nos valores definidos no código JavaScript , também não funciona para entradas virtuais.
Vinculando o input
evento para todos os input
s (e textarea
s e select
s) na sua página não irá funcionar em navegadores mais antigos e, como todas as soluções de tratamento de evento mencionado acima, não suporta desfazer. Quando um usuário altera uma caixa de texto e a desfaz, ou marca e desmarca uma caixa de seleção, o formulário ainda é considerado sujo.
E quando você deseja implementar mais comportamentos, como ignorar certos elementos, terá ainda mais trabalho a fazer.
Não reinvente a roda:
Portanto, antes de pensar em implementar essas soluções e todas as soluções necessárias, perceba que você está reinventando a roda e está propenso a encontrar problemas que outras pessoas já resolveram para você.
Se seu aplicativo já usa jQuery, você também pode usar código testado e mantido em vez de criar o seu próprio e usar uma biblioteca de terceiros para tudo isso. jQuery tem certeza? plugin funciona muito bem, veja sua página de demonstração . É simples assim:
<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>
Mensagens personalizadas não suportadas em qualquer lugar
Observe que o Firefox 4 não suporta mensagens personalizadas nesta caixa de diálogo. A partir de abril de 2016, o Chrome 51 está sendo implementado, no qual as mensagens personalizadas também estão sendo removidas .
Algumas alternativas existem em outras partes deste site, mas acho que uma caixa de diálogo como essa é clara o suficiente:
Deseja sair deste site?
As alterações feitas podem não ser salvas.
Leave Stay