web-dev-qa-db-ja.com

IEのjavascript:hrefリンクによってwindow.onbeforeunloadがトリガーされないようにするにはどうすればよいですか?

私は、ユーザーがページを離れるとフォームデータが失われることをユーザーに警告するフォーム用のフェイルセーフを構築しています(Gmailと同様)。

window.onbeforeunload = function () {    
        if (formIsDirty) {
            return "You have unsaved data on this form. Don't leave!";
        }
}

上記の関数はFirefoxで適切に機能しますが、IEでは、任意のhrefリンクによってトリガーされます。他のページではなく、javascriptへのリンクであるリンクでもトリガーされます。

例えば....

<a href='javascript:someFunction();'>click</a>

ユーザーがボタンをクリックするだけでページを離れているとユーザーに思わせたくないので、これを回避する方法があるかどうか疑問に思っています。 さまざまなリンクをすべて書き換えるオプションはありません組み込みで多数あるためです。

何か案は?

27
Maxx

これらのリンクにカーソルを合わせると、onbeforeunloadを削除して再割り当てできます。

jQuery(
  function($)
  {
      //store onbeforeunload for later use
    $(window).data('beforeunload',window.onbeforeunload);  

      //remove||re-assign onbeforeunload on hover 
    $('a[href^="javascript:"]')
      .hover( 
             function(){window.onbeforeunload=null;},
             function(){window.onbeforeunload=$(window).data('beforeunload');}
            );

  }
);
36
Dr.Molle

私は同様の問題に遭遇し、非常に簡単な解決策を見つけました:

$("a").mousedown(function() {
    $(window).unbind();
});

これにより、クリックイベントがトリガーされる直前にonbeforeunloadイベントが削除されます。

7
Ginchen

代わりに、スクリプトをclickイベントハンドラーに移動します。JavaScriptを使用していないユーザーのためのフォールバックページを使用します。

_<a href="foo.html" onclick="someFunction(); return false">click</a>
_

控えめなJSチャンピオンはおそらくonclick属性の使用に反対するでしょうが、実際にはそれが機能することは、イベントハンドラーを追加する最も簡単な方法であり、例を提供する最も簡単な方法です。問題をより適切に分離するには、代わりにDOM0 onclickプロパティ、addEventListener()/attachEvent()またはライブラリを使用できます。

3
Tim Down

Aタグのhrefにブックマーク記号を含めても、onclickイベントを使用してJavaScriptを含めることができるはずです。

<a href="#" onclick='someFunction();'>click</a>

私はいくつかのテストを実行しましたが、onbeforeunloadイベントをトリガーせずにJavaScriptを実行しているようです。これが他の人にも有効かどうか、またはこの方法でタグを実装した後も同じ問題が発生するかどうか知りたいと思います。

1
Lone Ranger

(他のいくつかの回答と同様に、これにはJavaScriptのバインド方法を変更する必要があります。それが機能しない場合は無視してください。)

IE 7からIE 10で、preventDefaultでjQuery .click()を使用するだけで、onbeforeunloadメッセージ(IE 11は、どのテストケースでもbeforeunloadメッセージを表示しません。)これは、hrefが '#'でもjavascript:void(0)でも同じです。 attachEvent/addEventListenerは直接使用されますが、テストしていません。

以下のデモが http://jsbin.com/tatufehe/1 にあります。両方のバージョン(緑色)でpreventDefaultが機能します(beforeunloadダイアログを表示しないでください)。 preventDefaultのないものはそれを示します(比較として)。


$( document ).ready( function () {
  $( 'a' ).click( function ( evt ) {
    $( '#display' ).text( 'You clicked: ' + $( this ).text() );

    if ( $(this).hasClass( 'withPreventDefault' ) ) {
      evt.preventDefault();
    }
  } );
})

window.onbeforeunload = function () {
  return "Are you sure you want to leave?";   
};

<p id="display"></p>

<p><a class="withPreventDefault" href="#">Number sign link *with* preventDefault</a></p>

<p><a class="withPreventDefault" href="javascript:void(0);">JavaScript href link *with* preventDefault</a></p>

<p><a href="javascript:void(0);">JavaScript href link *without* preventDefault</a></p>
1

ユーザーのマウスがリンク上にあり、キーボードでページの更新をトリガーしたり、キーボードでリンクをアクティブにしたりしても、プロンプトは表示されません。したがって、Dr.Molleアプローチはこのまれなケースでは機能しません。

0
danial