Window.onbeforeunloadを使用して、フォーム上の値を変更した後にユーザーが移動できないようにします。これは正常に機能していますが、ユーザーがフォームを送信したときに警告が表示されることを除きます(望ましくありません)。
フォームの送信時に警告を表示せずにこれを行うにはどうすればよいですか?
現在のコード:
var formHasChanged = false;
$(document).on('change', 'form.confirm-navigation-form input, form.confirm-navigation-form select, form.confirm-navigation-form textarea', function (e) {
formHasChanged = true;
});
$(document).ready(function () {
window.onbeforeunload = function (e) {
if (formHasChanged) {
var message = "You have not saved your changes.", e = e || window.event;
if (e) {
e.returnValue = message;
}
return message;
}
}
});
フォームの送信イベントを使用してフラグを設定するとうまくいく場合があります。
var formHasChanged = false;
var submitted = false;
$(document).on('change', 'form.confirm-navigation-form input, form.confirm-navigation-form select, form.confirm-navigation-form textarea', function (e) {
formHasChanged = true;
});
$(document).ready(function () {
window.onbeforeunload = function (e) {
if (formHasChanged && !submitted) {
var message = "You have not saved your changes.", e = e || window.event;
if (e) {
e.returnValue = message;
}
return message;
}
}
$("form").submit(function() {
submitted = true;
});
});
.on()を使用してonbeforeunloadをバインドし、次に.off()を使用してフォーム送信でアンバインドできます。
$(document).ready(function () {
// Warning
$(window).on('beforeunload', function(){
return "Any changes will be lost";
});
// Form Submit
$(document).on("submit", "form", function(event){
// disable warning
$(window).off('beforeunload');
});
}
submit() イベントを処理できます。これはフォームの送信時にのみ発生します。
そのイベント内で、フラグ変数formHasChanged
をfalseに設定して、アンロードを続行できるようにします。また、単なる提案ですが、そのフラグ変数の目的が変更されるため、「warnBeforeUnload」のような名前に変更することができます
$(document).submit(function(){
warnBeforeUnload = false;
});
これに対するより良い解決策を探していました。必要なのは、1つまたは複数のトリガーを「本当によろしいですか」の作成から除外することです。ダイアログボックス。そのため、ますます多くの副作用に対する回避策を作成するべきではありません。送信ボタンのclick
イベントなしでフォームが送信された場合はどうなりますか?クリックハンドラーがisDirty
ステータスを削除しても、その後フォーム送信がブロックされるとどうなりますか?トリガーの動作を変更できますが、適切な場所はダイアログを処理するロジックです。送信ボタンのsubmit
イベントにバインドするのではなく、フォームのclick
イベントにバインドすることは、このスレッドの答えが以前見た他のいくつかのものより優れている点ですが、このIMHOは間違ったアプローチを修正します。
onbeforeunload
イベントのイベントオブジェクトを掘り下げた後、.target.activeElement
プロパティ。元のイベントをトリガーした要素を保持します。だから、いや、それはボタンやリンク、または私たちがクリックしたもの(またはブラウザ自体が離れて移動した場合は何もありません)です。 「よろしいですか?」ダイアログロジックは、次の2つのコンポーネントに縮小します。
フォームのisDirty
処理:
$('form.pleaseSave').on('change', function() {
$(this).addClass('isDirty');
});
「よろしいですか?」ダイアログロジック:
$(window).on('beforeunload', function(event) {
// if form is dirty and trigger doesn't have a ignorePleaseSave class
if ($('form.pleaseSave').hasClass('isDirty')
&& !$(event.target.activeElement).hasClass('ignorePleaseSave')) {
return "Are you sure?"
}
// special hint: returning nothing doesn't summon a dialog box
});
それは単純です。回避策は必要ありません。トリガー(送信および他のアクションボタン)にignorePleaseSave
クラスと、ダイアログをpleaseSave
クラスに適用したいフォームを与えるだけです。ページをアンロードする他のすべての理由は、「よろしいですか?」を呼び出します。ダイアログ。
追伸ここではjQueryを使用していますが、.target.activeElement
プロパティは、プレーンJavaScriptでも使用できます。