Krótka, zła odpowiedź:
Możesz to zrobić, obsługując beforeunload
zdarzenie i zwracając ciąg inny niż zero :
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.
});
Problem z tym podejściem polega na tym, że przesłanie formularza powoduje także zwolnienie zdarzenia . Można to łatwo naprawić, dodając flagę, którą przesyłasz formularz:
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.
});
};
Następnie dzwoniąc do setera podczas przesyłania:
<form method="post" onsubmit="setFormSubmitting()">
<input type="submit" />
</form>
Ale czytaj dalej ...
Długa, poprawna odpowiedź:
Nie chcesz również wyświetlać tej wiadomości, gdy użytkownik nic nie zmienił w formularzach . Jednym z rozwiązań jest użycie beforeunload
zdarzenia w połączeniu z flagą „brudną”, która uruchamia monit tylko wtedy, gdy jest naprawdę istotny.
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.
});
};
Aby wdrożyć tę isDirty
metodę, istnieją różne podejścia.
Możesz używać jQuery i serializacji formularzy , ale to podejście ma pewne wady. Najpierw musisz zmienić kod, aby działał w dowolnej formie ( $("form").each()
zrobi to), ale największym problemem jest to, że jQuery serialize()
będzie działał tylko na nazwanych, nie wyłączonych elementach, więc zmiana dowolnego wyłączonego lub nienazwanego elementu nie wyzwoli brudnej flagi. Istnieją obejścia tego problemu , takie jak dokonywanie kontroli tylko do odczytu zamiast włączania, serializacji, a następnie ponownego wyłączania kontroli.
Wydaje się, że wydarzenia powinny się odbyć. Możesz spróbować odsłuchać naciśnięcia klawiszy . To wydarzenie ma kilka problemów:
- Nie uruchamia się w polach wyboru, przyciskach radiowych ani innych elementach zmienianych za pomocą myszy.
- Uruchomi się w przypadku nieistotnych naciśnięć klawiszy, takich jak Ctrlklawisz.
- Nie wyzwala wartości ustawionych za pomocą kodu JavaScript.
- Nie uruchamia się przy wycinaniu lub wklejaniu tekstu w menu kontekstowych.
- Nie będzie działać w przypadku wirtualnych danych wejściowych, takich jak datepickers lub upiększające pola wyboru / przyciski radiowe, które zapisują swoją wartość w ukrytych danych wejściowych za pomocą JavaScript.
change
Wydarzenie również nie wywołuje na wartościach ustalonych z kodu JavaScript , więc również nie będą działać dla wejść wirtualnych.
Wiązania input
zdarzenie do wszystkich input
s (i textarea
S i select
S) na swojej stronie nie będzie działać na starszych przeglądarkach i, jak wszystkie rozwiązania obsługi zdarzeń wymienionych powyżej, nie obsługuje cofania. Gdy użytkownik zmieni pole tekstowe, a następnie je cofnie, lub zaznaczy i odznaczy pole wyboru, formularz nadal będzie uważany za brudny.
A jeśli chcesz wprowadzić więcej zachowań, takich jak ignorowanie niektórych elementów, będziesz musiał wykonać jeszcze więcej pracy.
Nie wymyślaj koła ponownie:
Zanim więc pomyślisz o wdrożeniu tych rozwiązań i wszystkich wymaganych obejść, zdaj sobie sprawę, że zmieniasz kierownicę i masz skłonność do problemów, które inni już dla ciebie rozwiązali.
Jeśli twoja aplikacja korzysta już z jQuery, możesz równie dobrze użyć sprawdzonego, utrzymywanego kodu zamiast zwijania własnego, i do tego wszystkiego użyj biblioteki trzeciej części. jQuery's Are You Sure? wtyczka działa świetnie, zobacz ich stronę demo . To takie proste:
<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>
Niestandardowe wiadomości nie są obsługiwane wszędzie
Pamiętaj, że Firefox 4 nie obsługiwał niestandardowych wiadomości w tym oknie dialogowym. Od kwietnia 2016 r. Wdrażany jest Chrome 51, w którym usuwane są również niestandardowe wiadomości .
Niektóre alternatywy istnieją gdzie indziej na tej stronie, ale myślę, że takie okno dialogowe jest wystarczająco jasne:
Czy chcesz opuścić tę stronę?
Wprowadzone zmiany mogą nie zostać zapisane.
Leave Stay