Risposta breve e sbagliata:
Puoi farlo gestendo l' beforeunload
evento e restituendo una stringa non nulla :
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.
});
Il problema con questo approccio è che l' invio di un modulo genera anche l'evento di scaricamento . Questo problema viene risolto facilmente aggiungendo il flag che stai inviando un modulo:
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.
});
};
Quindi chiamare il setter durante l'invio:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
Ma continua a leggere ...
Risposta lunga e corretta:
Inoltre, non vuoi mostrare questo messaggio quando l'utente non ha modificato nulla nei tuoi moduli . Una soluzione è utilizzare l' beforeunload
evento in combinazione con un flag "sporco", che attiva il prompt solo se è realmente rilevante.
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.
});
};
Ora per implementare il isDirty
metodo, ci sono vari approcci.
È possibile utilizzare jQuery e la serializzazione dei moduli , ma questo approccio presenta alcuni difetti. Per prima cosa devi modificare il codice per funzionare su qualsiasi modulo ( $("form").each()
lo farà), ma il problema maggiore è che jQuery serialize()
funzionerà solo su elementi con nome, non disabilitati, quindi la modifica di qualsiasi elemento disabilitato o senza nome non attiverà il flag sporco. Esistono soluzioni alternative per questo , come rendere i controlli di sola lettura anziché abilitare, serializzare e quindi disabilitare nuovamente i controlli.
Quindi gli eventi sembrano la strada da percorrere. Puoi provare ascoltare i tasti premuti . Questo evento presenta alcuni problemi:
- Non si attiva su caselle di controllo, pulsanti di opzione o altri elementi che vengono modificati tramite l'input del mouse.
- Attiverà la pressione di tasti irrilevanti come la Ctrlchiave.
- Non si innescherà sui valori impostati tramite il codice JavaScript.
- Non si innescherà se si taglia o incolla il testo attraverso i menu di scelta rapida.
- Non funzionerà con input virtuali come datepicker o beautifiers checkbox / radiobutton che salvano il loro valore in un input nascosto tramite JavaScript.
L' change
evento anche non attiva su valori impostati dal codice JavaScript , quindi anche non funziona per gli ingressi virtuali.
Associare l' input
evento a tutti gli input
s (e se textarea
e select
) della tua pagina non funzionerà sui browser più vecchi e, come tutte le soluzioni di gestione degli eventi sopra menzionate, non supporta l'annullamento. Quando un utente modifica una casella di testo e quindi annulla tale opzione, oppure seleziona e deseleziona una casella di controllo, il modulo viene comunque considerato sporco.
E quando vuoi implementare più comportamenti, come ignorare determinati elementi, avrai ancora più lavoro da fare.
Non reinventare la ruota:
Quindi, prima di pensare di implementare quelle soluzioni e tutte le soluzioni alternative necessarie, renditi conto che stai reinventando la ruota e sei incline a imbatterti in problemi che altri hanno già risolto per te.
Se l'applicazione utilizza già jQuery, è possibile utilizzare anche codice testato e gestito invece di distribuire il proprio, e utilizzare una libreria di terze parti per tutto questo. Sei sicuro di jQuery? plugin funziona alla grande, vedere la loro pagina demo . È semplice come questo:
<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>
Messaggi personalizzati non supportati ovunque
Nota che Firefox 4 non supportava messaggi personalizzati in questa finestra di dialogo. A partire da aprile 2016, Chrome 51 è stato lanciato in cui vengono rimossi anche i messaggi personalizzati .
Alcune alternative esistono altrove in questo sito, ma penso che una finestra di dialogo come questa sia abbastanza chiara:
Vuoi lasciare questo sito?
Le modifiche apportate potrebbero non essere salvate.
Leave Stay