38

私は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;
        }
    }
});
4

4 に答える 4

38

フォームの送信イベントを使用してフラグを設定すると、うまくいく場合があります。

 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;
     });
});
于 2012-08-01T20:03:33.647 に答える
17

.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');
    });
}
于 2014-08-26T17:04:20.183 に答える
11

フォームの送信時にのみ発生するsubmit()イベントを処理できます。

そのイベント内で、フラグ変数formHasChangedをfalseに設定して、アンロードを続行できるようにします。また、単なる提案ですが、そのフラグ変数の目的が変更されるため、「warnBeforeUnload」のような名前に変更することをお勧めします。

$(document).submit(function(){
    warnBeforeUnload = false;
});
于 2012-08-01T20:01:50.630 に答える
3

私はこれに対するより良い解決策を探していました。私たちが望んでいるのは、「Are yousure?」の作成から1つ以上のトリガーを除外することです。ダイアログボックス。したがって、ますます多くの副作用に対する回避策をますます作成するべきではありません。click送信ボタンのイベントなしでフォームが送信された場合はどうなりますか?クリックハンドラーがステータスを削除しisDirtyた後、フォーム送信がブロックされた場合はどうなりますか?確かにトリガーの動作を変更することはできますが、適切な場所はダイアログを処理するロジックです。submit送信ボタンのイベントにバインドする代わりにフォームのイベントにバインドするclickことは、私が以前に見た他のいくつかのスレッドよりもこのスレッドの回答の利点ですが、このIMHOは間違ったアプローチを修正するだけです。

イベントのイベントオブジェクトを掘り下げた後、元々イベントをトリガーした要素を保持するプロパティonbeforeunloadを見つけました。.target.activeElementつまり、それはボタンやリンク、またはクリックしたものです(または、ブラウザー自体が移動した場合は何もありません)。私たちの「よろしいですか?」次に、ダイアログロジックは次の2つのコンポーネントに縮小されます。

  1. フォームのisDirty処理:

    $('form.pleaseSave').on('change', function() {
      $(this).addClass('isDirty');
    });
    
  2. 「よろしいですか?」ダイアログロジック:

    $(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。ページをアンロードする他のすべての理由は、「よろしいですか?」を呼び出します。ダイアログ。

.target.activeElementPSここではjQueryを使用していますが、このプロパティはプレーンJavaScriptでも利用できると思います。

于 2015-08-26T18:47:15.390 に答える