Réponse courte et fausse:
Vous pouvez le faire en manipulation de l' beforeunload
événement et en retournant une chaîne non nulle :
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.
});
Le problème avec cette approche est que l' envoi d'un formulaire déclenche également l'événement de déchargement . Ceci est résolu facilement en ajoutant le drapeau que vous soumettez un formulaire:
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.
});
};
Puis appeler le passeur lors de la soumission:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
Mais lisez la suite ...
Réponse longue et correcte:
Vous ne voulez pas non plus afficher ce message lorsque l'utilisateur n'a rien changé sur vos formulaires . Une solution consiste à utiliser l' beforeunload
événement en combinaison avec un indicateur "sale", qui ne déclenche l'invite que s'il est vraiment pertinent.
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.
});
};
Maintenant, pour mettre en œuvre la isDirty
méthode, il existe différentes approches.
Vous pouvez utiliser jQuery et sérialiser un formulaire , mais cette approche présente quelques défauts. Vous devez d'abord modifier le code pour travailler sur n'importe quelle forme ( $("form").each()
fera l'affaire), mais le plus gros problème est que jQuery serialize()
ne fonctionnera que sur les éléments nommés et non désactivés, donc la modification de tout élément désactivé ou non nommé ne déclenchera pas le drapeau sale. Il existe des solutions pour cela , comme rendre les contrôles en lecture seule au lieu d'activer, de sérialiser puis de désactiver à nouveau les contrôles.
Les événements semblent donc la voie à suivre. Vous pouvez essayer d' écouter les touches . Cet événement a quelques problèmes:
- Ne se déclenche pas sur les cases à cocher, les boutons radio ou d'autres éléments modifiés par la souris.
- Se déclenchera pour les touches non pertinentes comme la Ctrltouche.
- Ne se déclenche pas sur les valeurs définies via le code JavaScript.
- Ne se déclenche pas lors de la coupe ou du collage de texte via les menus contextuels.
- Ne fonctionnera pas pour les entrées virtuelles comme les sélecteurs de date ou les embellisseurs de case à cocher / radiobutton qui enregistrent leur valeur dans une entrée cachée via JavaScript.
L' change
événement a également ne déclenche pas sur les valeurs définies à partir du code JavaScript , donc cela ne fonctionnera pas pour les entrées virtuelles.
La liaison de l' input
événement à tous les input
s (et textarea
s et select
s) de votre page ne fonctionnera pas sur les anciens navigateurs et, comme toutes les solutions de gestion d'événements mentionnées ci-dessus, ne prend pas en charge l'annulation. Lorsqu'un utilisateur modifie une zone de texte, puis l'annule, ou vérifie et décoche une case à cocher, le formulaire est toujours considéré comme sale.
Et lorsque vous souhaitez implémenter plus de comportements, comme ignorer certains éléments, vous aurez encore plus de travail à faire.
Ne réinventez pas la roue:
Donc, avant de penser à mettre en œuvre ces solutions et toutes les solutions de contournement nécessaires, réalisez que vous réinventez la roue et que vous êtes enclin à rencontrer des problèmes que d'autres ont déjà résolus pour vous.
Si votre application utilise déjà jQuery, vous pouvez également utiliser du code testé et maintenu au lieu de lancer le vôtre, et utiliser une bibliothèque tierce pour tout cela. Êtes-vous sûr de jQuery? plugin fonctionne très bien, voir leur page de démonstration . C'est aussi simple que ça:
<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>
Messages personnalisés non pris en charge partout
Notez que Firefox 4 ne prend pas en charge les messages personnalisés dans cette boîte de dialogue. Depuis avril 2016, Chrome 51 est déployé dans lequel les messages personnalisés sont également supprimés .
Certaines alternatives existent ailleurs sur ce site, mais je pense qu'un dialogue comme celui-ci est assez clair:
Voulez-vous quitter ce site?
Les modifications que vous avez apportées peuvent ne pas être enregistrées.
Leave Stay