refused to allow the document to be unloaded

beforeunload イベント (DOM)

[33] beforeunload は、navigate閲覧文脈を閉じるために文書活性文書でなくなろうとしていることを知らせるDOMイベントです。

[34] スクリプトは、このイベントを使って、必要があれば利用者に対して本当に処理を続行するかどうか利用者エージェントに確認させることができます。

[35] 例えば文書を編集する Webアプリケーションでは、変更がすべてサーバー上に保存されていない時に、 そのまま遷移または閉じて変更を破棄しても良いかを利用者に尋ねるために本イベントを使うことができます。

仕様書

確認ダイアログ

[29] beforeunload イベントで文字列が指定されたかイベント取り消しされた場合には、 利用者に対して unload を続行するかどうか確認するモーダルダイアログが (原則として) 表示されます。

[30] このダイアログには、 利用者の可能な選択肢として続行するボタンと続行しないボタンが表示されます。

[45] かつては著者が指定した文字列があれば、それを表示することになっていました。 しかし悪意ある著者利用者を欺くために使うことがあるので、 この機能は廃止されました。

[31] termination nesting level が設定される (>>32) ため、 beforeunload 中では confirm は使うことができず、こちらの方法で間接的にモーダルダイアログを表示させる必要があります。

[36] 仕様上はモーダルダイアログを表示するべきことは MUST ではなく SHOULD となっていますが、利用者インターフェイスに関する要件であることや、 利用者に対する DoS攻撃に乱用される可能性も否定できないことなどを踏まえて表示しない余地を与えているものと思われます。 そのような特殊な状況や、仕様上除外されている砂箱化された状態を除いて、 モーダルダイアログを表示しないような実装は Web互換ではありません。

[43] 表示についてはモーダルダイアログも参照。

処理

[7] prompt to unload a document は、 文書再帰フラグについて、 次のようにしなければなりません >>6

  1. [32] 文書イベントループtermination nesting level1 インクリメントします。
  2. [54] 文書ignore-opens-during-unload counter1 インクリメントします。
  3. [55] イベントを、 BeforeUnloadEvent イベントを作成した結果に設定します。
  4. [56] イベントを、 beforeunload に設定します。
  5. [57] イベント取り消し可能を、に設定します。
  6. [58] イベントdispatch します。
    対象
    文書Window
  7. [63] 文書イベントループtermination nesting level1 デクリメントします。
  8. [64] イベントdispatchでいずれかのイベントリスナーが実行されていたらなら、
    1. [65] 文書salvageable を、に設定します。
  9. [72] refused to allow the document to be unloaded を、に設定します。
  10. [26]
    ... のすべての条件を満たすなら、
    1. [49] 利用者に対して unload を望むか確認します。
    2. [40] 利用者の応答があるまで、 pause します。
    3. [41] 利用者が unload を望まないと応答したら、
      1. [50] refused to allow the document to be unloaded を、に設定します。
  11. [71] 再帰の場合、
    1. [66] 文書子孫閲覧文脈のリストの各閲覧文脈について、
      1. [73] 結果を、prompt to unload を実行した結果に設定します。
        文書
        閲覧文脈活性文書
        再帰フラグ
      2. [74] 結果の場合、
        1. [75] refused to allow the document to be unloaded を、に設定します。
        2. [76] 閲覧文脈ループを抜けます。
      3. [67] 閲覧文脈活性文書salvageableの場合、
        1. [68] 文書salvageable を、に設定します。
  12. [69] 文書ignore-opens-during-unload counter1 デクリメントします。
  13. [70] refused to allow the document to be unloaded を返します。

[51] 利用者に確認するかどうかの判断は利用者エージェントに委ねられていますが、 例えば、利用者が当該閲覧文脈対話していない状態なら、 省くことができます >>13。裏のタブで勝手に navigate が発生した場合などが該当しそうです。

[42] 利用者に対する確認の表示については、モーダルダイアログを参照。

[8] prompt to unload a documentnavigate から呼び出されます。

[10] 素片識別子へのスクロールしかしない場合は呼び出されませんが、 fetch を行う場合などは (最終的にダウンロードなどに至るとしても、 それが決まる前に) 呼び出されます。詳しくは navigate を参照。

[9] prompt to unload a document の実行中は、 navigate は何もしません。 つまり beforeunload イベント内ではページ遷移の開始が抑制されます。

navigate を参照。なお ⊿ を指定した履歴の探索は抑制されませんが、 実際の処理は別のタスクタスクキューに入れる形で実行されるので、 beforeunload イベント内で同期的にページ遷移が開始されることはありません。

[11] prompt to unload a document は ⊿ を指定した履歴の探索や、 window.open や、閲覧文脈を閉じる際にも呼び出されます。

[12] prompt to unload a document が呼び出された場合、 refuse されていなければ、その後 unload a document が呼び出されることになります。

BeforeUnloadEvent インターフェイス

[15] BeforeUnloadEvent インターフェイス >>13 は、 beforeunload イベントで使われます。

[17] BeforeUnloadEvent インターフェイスは、 文書環境晒されています >>13

[16] BeforeUnloadEvent インターフェイスは、 Event インターフェイス継承しています >>13

[18] 他のイベントインターフェイスとは違って、コンストラクターはありません。

[19] BeforeUnloadEvent インターフェイスは、 returnValue IDL属性を持ちます >>13

他のイベントインターフェイスの属性とは違って、読み書きの両方が可能です。

[20] returnValue IDL属性は、 DOMString を設定、取得できる属性で、初期値は空文字列です >>13イベントリスナー内で著者が適切な値を設定することが想定されていました。

[46] このIDL属性は、後方互換性のためのものです >>13。 値が設定されているかどうかが処理に反映されますが、値そのものは無視されます。 著者は、 preventDefault などを使うべきです >>13

[21] prompt to unload a document は、 著者returnValue に非空文字列を設定したら、 それをモーダルダイアログに表示することになっていました。

[22] IEのイベントモデルでは、イベントハンドラー返り値イベントオブジェクトの returnValue を設定するのと同義でした。現在の DOM では、唯一 BeforeUnloadEvent にのみ returnValue が残っています。

onbeforeunload 属性

[14] onbeforeunload イベントハンドラー属性は、 他のイベントハンドラーとは違って、返り値イベントオブジェクトの returnValue IDL属性の値 (を文字列化したもの) に設定されます。

歴史

[2] IEでのonBeforeUnload の挙動 | Inside ASCADE ( 版) <http://inside.ascade.co.jp/node/58>

<a> タグの href で javascipt を呼び出した場合に location を変化させない(つもり)にもかかわらず、onBeforeunload イベントが発生したことです。ちなみにFirefoxではこの場合にイベントは発生しません。

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

[3] beforeunload 内で img により fetch を行うと、 ChromeIE10 では実際にアクセスが発生しますが、 Firefox では発生しません。

[4] Web Applications 1.0 r8282 OnBeforeUnloadEventHandler is supposed to allow null return values (and some markup error fixes, oops) ( ( 版)) <http://html5.org/tools/web-apps-tracker?from=8281&to=8282>

[5] IRC logs: freenode / #whatwg / 20150115 ( ( 版)) <http://krijnhoetmer.nl/irc-logs/whatwg/20150115#l-693>

[23] Update on standardizing shadow DOM and custom elements — Anne’s Blog ( 版) <https://annevankesteren.nl/2015/07/shadow-dom-custom-elements-update>

[24] IRC logs: freenode / #whatwg / 20150727 ( 版) <http://krijnhoetmer.nl/irc-logs/whatwg/20150727>

[25] Block modal dialogs by default in sandboxed documents · whatwg/html@bbccfc9 ( 版) <https://github.com/whatwg/html/commit/bbccfc976754def0c187ac8ce5891d2fb20dfc15>

[37] Remove the storage mutex due to lack of implementation · whatwg/html@1b918cf ( 版) <https://github.com/whatwg/html/commit/1b918cf72fcbba011f83b92ab5d1f483fb1cafa3>

[38] Allow truncation of alert/confirm/prompt text · whatwg/html@56f5c5e ( 版) <https://github.com/whatwg/html/commit/56f5c5e39b8b43b4bd4a8007fdc56ad797a5b2a7>

[44] Ignore beforeunload event return value · whatwg/html@01d9870 ( 版) <https://github.com/whatwg/html/commit/01d9870a6873e6d6410c3abf9fe38533646631b9>

[39] 25002 – Event.returnValue ( 版) <https://www.w3.org/Bugs/Public/show_bug.cgi?id=25002>

[47] Be more explicit that prompting before unloading is optional ( (domenic著, )) <https://github.com/whatwg/html/commit/8ef5d945d9c4298a0d66f81543f6a7e83634f39b>

[52] [] (0) Placeholder for beforeunload/unload; interaction of document.o… ( (Hixie著, )) <https://github.com/whatwg/html/commit/c1994a485446ab0fbfb7048df10bb081947f6405>

[53] API Deprecations and Removals in Chrome 51 | Web Updates - Google Developers ( ()) <https://developers.google.com/web/updates/2016/04/chrome-51-deprecations#remove-custom-messages-in-onbeforeload-dialogs>

A window’s onbeforeunload property may be set to a function that returns a string that is shown to the user in a dialog box to confirm that the user wants to navigate away. This was intended to prevent users from losing data during navigation. Unfortunately, it is often used to scam users.

Starting in Chrome 51, a custom string will no longer be shown to the user. Chrome will still show a dialog to prevent users from losing data, but it’s contents will be set by the browser instead of the web page.

With this change, Chrome will be consistent with Safari 9.1 and later, as well as Firefox 4 and later.

[59] Fix onbeforeunload event handler processing (domenic著, ) <https://github.com/whatwg/html/commit/fb7e621eab8a437df7ac524e547e31e117b7fce5>

[60] Fix event handler processing algorithm special cases (domenic著, ) <https://github.com/whatwg/html/commit/c065e991b65e10a1fc77ba77fed9f0822ff6858b>

[61] Chromium policy on JavaScript dialogs  |  Web  |  Google Developers ( ()) <https://developers.google.com/web/updates/2017/03/dialogs-policy>

[77] document.createEvent() supports lots of events that most UAs do not support initializers for · Issue #362 · whatwg/dom () <https://github.com/whatwg/dom/issues/362>

[78] document.open() simplifications, part 1 (TimothyGu著, ) <https://github.com/whatwg/html/commit/6f769b8089a843066aa19f5991405bf4c84458b3>

[79] How should document.open handle the beforeunload handler tearing down the world? · Issue #3306 · whatwg/html () <https://github.com/whatwg/html/issues/3306>

[80] document.open() simplifications: realm creation, unloading, tasks removal by TimothyGu · Pull Request #3918 · whatwg/html () <https://github.com/whatwg/html/pull/3918>