web-dev-qa-db-ja.com

OnBeforeUnloadダイアログをオーバーライドして自分のダイアログに置き換えるにはどうすればよいですか?

ページを離れる前に未保存の変更についてユーザーに警告する必要があります(かなり一般的な問題)。

window.onbeforeunload=handler

これは動作しますが、自分のテキストを折り返す標準的なメッセージが表示されるデフォルトのダイアログが表示されます。私は標準メッセージを完全に置き換える必要があるので、私のテキストは明確であるか、あるいは(さらに良いことに)jQueryを使ってダイアログ全体をモーダルダイアログに置き換える必要があります。

これまでのところ私は失敗しました、そして私は答えを持っているように思われる他の誰も見つけていません。それも可能ですか?

私のページのJavascript:

<script type="text/javascript">   
   window.onbeforeunload=closeIt;
</script>

CloseIt()関数:

function closeIt()
{
  if (changes == "true" || files == "true")
  {
      return "Here you can append a custom message to the default dialog.";
  }
}

JQueryとjqModalを使って、私は(カスタム確認ダイアログを使って)この種のことを試しました:

$(window).beforeunload(function() {
        confirm('new message: ' + this.href + ' !', this.href);
        return false;
    });

これも動作しません - beforeunloadイベントにバインドすることはできません。

334
flesh

あなたはonbeforeunloadのデフォルトの対話を修正することはできません、それであなたの最善の策はそれで働くことかもしれません。

window.onbeforeunload = function() {
    return 'You have unsaved changes!';
}

これがMicrosoftからの参照 です。

文字列がwindow.eventのreturnValueプロパティに割り当てられると、ダイアログボックスが表示され、ユーザーは現在のページに留まり、それに割り当てられている文字列を保持することができます。ダイアログボックスに表示されるデフォルトのステートメント「本当にこのページから移動しますか?...続行するには[OK]を、現在のページに留まるには[キャンセル]を押してください。」は削除または変更できません。

問題は以下のようです。

  1. onbeforeunloadが呼び出されると、ハンドラの戻り値をwindow.event.returnValueとして受け取ります。
  2. その後、戻り値を文字列として解析します(nullでない限り)。
  3. falseは文字列として解析されるので、ダイアログボックスが起動し、それから適切なtrue/falseが渡されます。

その結果、デフォルトのダイアログからそれを防ぐためにfalseonbeforeunloadに割り当てる方法はないようです。

JQueryに関する追加のメモ:

  • JQueryでイベントを設定すると、他のonbeforeunloadイベントも発生する可能性があるため、問題が生じる可能性があります。アンロードイベントのみを発生させたい場合は、単純なJavaScriptを使用してください。
  • jQueryにはonbeforeunloadへのショートカットがないので、一般的なbind構文を使用する必要があります。

    $(window).bind('beforeunload', function() {} );
    

編集09/04/2018:onbeforeunloadダイアログのカスタムメッセージはchrome-51以降廃止予定です(cf: リリースノート

291
Owen

jQuery を使用してIE 8、Chrome、Firefoxでテストした結果、私にとってうまくいったことは:

$(window).bind("beforeunload",function(event) {
    if(hasChanged) return "You have unsaved changes";
});

ここでIEと他のブラウザの動作に違いがあるため、プロンプトが必要ない場合は何も返さないことが重要です。

27
grebe

状況によっては、ボックスに対してできることは何もありませんが、リンクをクリックしている人を傍受することができます。私にとっては、これはほとんどのシナリオで努力する価値があり、代替として、unloadイベントを残しました。

標準のjQueryダイアログの代わりにBoxyを使用しました。こちらから入手できます。 http://onehackoranother.com/projects/jquery/boxy/

$(':input').change(function() {
    if(!is_dirty){
        // When the user changes a field on this page, set our is_dirty flag.
        is_dirty = true;
    }
});

$('a').mousedown(function(e) {
    if(is_dirty) {
        // if the user navigates away from this page via an anchor link, 
        //    popup a new boxy confirmation.
        answer = Boxy.confirm("You have made some changes which you might want to save.");
    }
});

window.onbeforeunload = function() {
if((is_dirty)&&(!answer)){
            // call this if the box wasn't shown.
    return 'You have made some changes which you might want to save.';
    }
};

別のイベントにアタッチして、どの種類のアンカーがクリックされたかをさらに絞り込むことができますが、これは私にとっても私がやりたいことにも役立ち、他の人が使用または改善するための例として役立ちます。私はこの解決策を望んでいる人のためにこれを共有すると思いました。

コードを切り取ったので、これではうまくいかないかもしれません。

20
Dan Power

1)onunloadではなくonbeforeunloadを使用してください。

2)重要なことは、return文を実行しないようにすることです。これによって、あなたのハンドラから戻ってこないようにするわけではありません。あなたは大丈夫を返しますが、あなたはあなたが関数の終わりに到達し、return文を実行しないことを確認することによってそれを行います。これらの条件下では、組み込みの標準ダイアログは表示されません。

3)onbeforeunloadを使用している場合は、unbeforeunloadハンドラーでajax呼び出しを実行してサーバーを片付けることができますが、それは同期のものでなければならず、onbeforeunloadハンドラーで応答を待って処理する必要があります。上記の条件(2))。私はこれをします、そしてそれはうまく働きます。あなたが同期のAjax呼び出しをするならば、応答が返ってくるまで、すべてが遅らせられます。サーバーからの返信を気にしないと考えて非同期のものを実行した場合、ページのアンロードは続行され、このプロセスによってajax呼び出しは中止されます(実行中のリモートスクリプトも含む)。

9
user1164763

メッセージの代わりにreturn;を配置してみてください。これは私にとってほとんどのブラウザで動作しています。 (これはダイアログのプレゼントを本当に防ぐだけです)

window.onbeforeunload = function(evt) {            
        //Your Extra Code
        return;
}
4
Donald Powell

スパムを避けるために、これをクロムで行うことはできません。詳細については、 javascript onbeforeunloadでカスタムメッセージが表示されない を参照してください。

3
Abhijeet

私は同じ問題に直面しました、私は私のメッセージでそれ自身のダイアログボックスを得ることは問題ありませんでした、しかし私が直面した問題は以下の通りでした。 2)ユーザーがキャンセルを選択した場合、私自身の確認メッセージが表示されてもブラウザのデフォルトのダイアログボックスが表示されます。

以下は私が私のマスターページに書いた私が見つけた解決策コードです。

function closeMe(evt) {
    if (typeof evt == 'undefined') {
        evt = window.event; }
    if (evt && evt.clientX >= (window.event.screenX - 150) &&
        evt.clientY >= -150 && evt.clientY <= 0) {
        return "Do you want to log out of your current session?";
    }
}
window.onbeforeunload = closeMe;
3
Imran Rizvi

ユーザーがどのボタン(OKまたはキャンセル)を押したかを検出することができます。これは、onunload関数が、ユーザーがページを離れることを選択した場合にのみ呼び出されるためです。この機能では、DOMが崩壊しているため、可能性は限られています。あなたはjavascriptを実行することができますが、ajax POSTは何もしないので自動ログアウトのためにこの方法を使うことはできません。しかし、それに対する解決策があります。 window.open( 'logout.php')がonunload関数で実行されたため、ユーザーは新しいウィンドウを開いてログアウトします。

function onunload = (){
    window.open('logout.php');
}

このコードは、ユーザーがページを離れるかアクティブウィンドウを閉じ、ユーザーが「logout.php」でログアウトしたときに呼び出されます。ログアウトphpがコードで構成されているとすぐに新しいウィンドウが閉じます。

window.close();
3
Tamas Cseh
 <script type="text/javascript">
        window.onbeforeunload = function(evt) {
            var message = 'Are you sure you want to leave?';
            if (typeof evt == 'undefined') {
                evt = window.event;
            }       
            if (evt) {
                evt.returnValue = message;
            }
            return message;
        } 
    </script>

http://www.codeprojectdownload.com から参照

1
Krishna Patel

特殊なバージョンの "bind"コマンド "one"を使用しようとしています。イベントハンドラが最初に実行されると、イベントハンドラとして自動的に削除されます。

$(window).one("beforeunload", BeforeUnload);
1
Riga