IEでのonBeforeUnload の挙動
Tagged:

Javascript で onBeforeunload を利用したときに IE の挙動が直感的な操作とは異なったため、調査をすることにしました。
何が直感的ではなかったかというと、<a> タグの href で javascipt を呼び出した場合に location を変化させない(つもり)にもかかわらず、onBeforeunload イベントが発生したことです。ちなみにFirefoxではこの場合にイベントは発生しません。

ちょっと調べたところ、MSDN に仕様があったので、挙動確認のサンプルを作成してみました。
各サンプルの実行はご覧のブラウザをIEに変更していただき 各sampleのTEST をクリックしてください。

MSDN onbeforeunload site : http://msdn.microsoft.com/en-us/library/ms536907.aspx

まずは window.onbeforeunload を設定

本エントリの最初に以下のJavascriptを記述してあります。

<script type="text/javascript">
window.onbeforeunload = function(e){
    return "サンプルメッセージ";
}
</script>
window.onbeforeunload 設定

では、MSDN の "To invoke" に記述されている方法を試していきます。

Close the current browser window.
  • ブラウザを閉じる
Navigate to another location by entering a new address or selecting a Favorite.
  • ロケーションバーにURLを入力する
  • お気に入りからURLを選択する

単純にロケーションバーにフォーカスあてて "same location" でEnterしても発生しますが。まぁここは勘弁しましょう。

Click the Back, Forward, Refresh, or Home button.
  • 戻る、進む、リロード、ホームボタンを押す
Click on an anchor that refers the browser to another Web page.
  • 別のページを参照している <a> タグをクリックする

href="#xx" によるページ内(same location)での移動は発生しない。
"another location(href="javascript:xx"によるJavaScript呼出しも含む)" の場合に onBeforeUnload イベントが発生。

sample:

id が a1 と a2 の anchor タグを作成し、a1 の href には "same location" を a2 の href には "another location" を設定。

<a> refers same location (<a id="a1" href="#">TEST</a>): TEST
<a> refers another location (<a id="a1" href="http://www.gogle.com/">TEST</a>): TEST
invoke JS in href (<a href="javascript:alert('href')">TEST</a>): TEST
Invoke the anchor.click method.
  • anchor.click メソッド呼び出しの場合。

href の参照先が "another location" の場合に onBeforeUnload イベントが発生。

sample:

invoke click method "a1" by document.getElementById('a1').click() TEST
invoke click method "a2" by document.getElementById('a2').click() TEST キャンセル時にエラーあり。
Invoke the document.write method.
  • document.write() メソッド呼び出しの場合。

sample:

document.write('new document') TEST
※TEST をクリックするとドキュメント全体が書き換わります
Invoke the document.open method.
  • document.open() メソッド呼び出しの場合。

sample:

document.open() TEST
Invoke the document.close method.
  • document.close() メソッド呼び出しの場合。

sample:

document.close() TEST

document.close 単体では動作しませんでした。document.open, document.write と合わせることで動作しそうな気もしますが現在未確認です。

Invoke the window.close method.
  • window.close() メソッド呼び出しの場合。

通常のアラートで「はい」をクリック後、onbeforeunload イベントが発生する。

sample:

window.close() TEST
Invoke the window.open method, providing the possible value _self for the window name.
  • window 名が "_self" の場合の window.open() メソッド呼び出しの場合。

sample:

window.open('#', '_self') TEST
window.open('http://www.google.com/', '_self') TESTキャンセル時にエラーあり。
window.open('#') TEST
Invoke the window.navigate or NavigateAndFind method.
  • window.navigate() か NavigateAndFind メソッド呼び出しの場合。

window.external.NavigateAndFind() の場合2度 onBeforeunload イベントが発生している。

sample:

window.navigate('http://www.google.com/') TEST
window.external.NavigateAndFind('http://www.google.com/', 'gogle', '_self') TEST
Invoke the location.replace method.
  • location.replace() メソッド呼び出しの場合。

sample:

location.replace('#') TEST
location.replace('http://www.google.com/') TEST
Invoke the location.reload method.
  • location.reload() メソッド呼び出しの場合。

sample:

location.reload() TEST
Specify a new value for the location.href property.
  • location.href に新しい location を設定した場合

sample:

location.href = '#' TEST
location.href = 'http://www.google.com/' TESTキャンセル時にエラーあり。
Submit a form to the address specified in the ACTION attribute via the INPUT type=submit control, or invoke the form.submit method.
  • INPUT type=submit ボタン及び form.submit によるフォーム送信時

sample:

form name="test"
document.test.submit() TEST
まとめ
  • 多少仕様の記述と異なるが大体MSDNのドキュメント通り
  • href="javascript:xx" でonBeforeunload が発生するのは少し困る
  • document.close ではonBeforeunload が発生しないが別に困らない

といった感じです。
「href="javascript:xx" でonBeforeunload が発生するのは少し困る」の件については、対処方法がMSDNのドキュメント(の下の方)にもありますし、いろいろな方が解決されているのでいまのところまとめる予定はありません。