-
Notifications
You must be signed in to change notification settings - Fork 4
/
296.txt
196 lines (148 loc) · 12 KB
/
296.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
[33] [DFN[[CODE(DOMe)@en[[[beforeunload]]]]]] は、[[navigate]] や[[閲覧文脈を閉じる]]ために[[文書]]が[[活性文書]]でなくなろうとしていることを知らせる[[DOMイベント]]です。
[34] [[スクリプト]]は、この[[イベント]]を使って、必要があれば[[利用者]]に対して本当に処理を続行するかどうか[[利用者エージェント]]に確認させることができます。
[EG[
[35] 例えば[[文書]]を編集する [[Webアプリケーション]]では、変更がすべて[[サーバー]]上に保存されていない時に、
そのまま遷移または閉じて変更を破棄しても良いかを[[利用者]]に尋ねるために本[[イベント]]を使うことができます。
]EG]
* 仕様書
[REFS[
- [6] '''[CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-04-25 04:40:19 +09:00]] 版) <https://html.spec.whatwg.org/#prompt-to-unload-a-document>'''
-- [13] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-04-25 04:40:19 +09:00]] 版) <https://html.spec.whatwg.org/#beforeunloadevent>
]REFS]
* 確認ダイアログ
[29] [CODE(DOMe)@en[[[beforeunload]]]] [[イベント]]で文字列が指定されたか[[イベント]]が[[取り消し]]された場合には、
[[利用者]]に対して unload を続行するかどうか確認する[[モーダルダイアログ]]が (原則として)
表示されます。
[30] このダイアログには、
[[利用者]]の可能な選択肢として続行するボタンと続行しないボタンが表示されます。
[HISTORY[
[45] かつては[[著者]]が指定した文字列があれば、それを表示することになっていました。
しかし悪意ある[[著者]]が[[利用者]]を欺くために使うことがあるので、
この機能は廃止されました。
]HISTORY]
[31] [[termination nesting level]] が設定される (>>32) ため、
[CODE(HTMLe)@en[[[beforeunload]]]] 中では [CODE(DOMe)@en[[[confirm]]]]
は使うことができず、こちらの方法で間接的に[[モーダルダイアログ]]を表示させる必要があります。
;; [36] 仕様上は[[モーダルダイアログ]]を表示するべきことは [MUST[MUST]] ではなく
[SHOULD[SHOULD]] となっていますが、[[利用者インターフェイス]]に関する要件であることや、
[[利用者]]に対する [[DoS攻撃]]に乱用される可能性も否定できないことなどを踏まえて表示しない余地を与えているものと思われます。
そのような特殊な状況や、仕様上除外されている[[砂箱化]]された状態を除いて、
[[モーダルダイアログ]]を表示しないような実装は [[Web互換]]ではありません。
[43] 表示については[[モーダルダイアログ]]も参照。
* 処理
[7] [DFN[[[prompt to unload a document]]]] は、次のようにしなければ[['''なりません''']]
[SRC[>>6]]。
[FIG(steps)[
= [32] [[文書]]の[[イベントループ]]の [[termination nesting level]] を一度[[インクリメント]]します。
= [[文書]]の [[ignore-opens-during-unload counter]] を一度[[インクリメント]]します。
= [[イベント]]を[[発火]]します。
[FIG(list members middle)[
[FIGCAPTION[
[[イベント]]
]FIGCAPTION]
:[[インターフェイス]]:[CODE(DOMi)@en[[[BeforeUnloadEvent]]]]
:[[イベント名]]:[CODE(DOMe)@en[[[beforeunload]]]]
:[[trusted]]:[[真]]
:[[bubbles]]:[[偽]]
:[[取り消し可能]]:[[真]]
:[[対象]]:[[文書]]の [CODE(DOMi)@en[[[Window]]]]
]FIG]
= [[文書]]の[[イベントループ]]の [[termination nesting level]] を一度[[デクリメント]]します。
= 先の[[イベント]]の[[発火]]でいずれかの[[イベントリスナー]]が実行されていたらなら、
[[文書]]の [[''salvageable'']] を[[偽]]に設定します。
= [26]
[FIG(list)[
- [28] [[文書]]の[[活性砂箱化フラグ集合]]の [[sandboxed modals flag]] が設定されておらず、
- [27] 先の[[イベント]]オブジェクトの [CODE(DOMa)@en[[[returnValue]]]]
が[[空文字列]]以外であるか、先の[[イベント]]が[[取り消し]]されていた
]FIG]
... なら、[[利用者]]に対して unload を望むか確認する[['''べきです''']]。
== [40] [[利用者]]の応答があるまで、 [[pause][pause (event loop)]] します。
== [41] [[利用者]]が unload を望まないと応答したら、
[DFN[[[refused to allow the document to be unloaded]]]] フラグを設定します。
= これが再帰呼び出しでないなら、
== [[文書]]の[[子孫閲覧文脈のリスト]]の各[[閲覧文脈]]について、
=== [[閲覧文脈]]の[[活性文書]]について [[prompt to unload a document]] を再帰的に呼び出します。
=== その結果が [[refused to allow the document to be unloaded]] なら、
[[refused to allow the document to be unloaded]] フラグを設定し、
各[[閲覧文脈]]についての処理を終えて次に進みます。
=== [[閲覧文脈]]の[[活性文書]]の [[''salvageable'']] が[[偽]]なら、
[[文書]]の [[''salvageable'']] も[[偽]]に設定します。
= [[文書]]の [[ignore-opens-during-unload counter]] を一度[[デクリメント]]します。
= [[refused to allow the document to be unloaded]] かどうかを返します。
]FIG]
;; [42] [[利用者]]に対する確認の表示については、[[モーダルダイアログ]]を参照。
[8] [[prompt to unload a document]] は [[navigate]] から呼び出されます。
;; [10] [[素片識別子へのスクロール]]しかしない場合は呼び出されませんが、
[[fetch]] を行う場合などは (最終的に[[ダウンロード]]などに至るとしても、
それが決まる前に) 呼び出されます。詳しくは [[navigate]] を参照。
[9] [[prompt to unload a document]] の実行中は、 [[navigate]] は何もしません。
つまり [CODE(DOMe)@en[[[beforeunload]]]] [[イベント]]内ではページ遷移の開始が抑制されます。
;; [[navigate]] を参照。なお ⊿ を指定した[[履歴の探索]]は抑制されませんが、
実際の処理は別の[[タスク]]を[[タスクキュー]]に入れる形で実行されるので、
[CODE(DOMe)@en[[[beforeunload]]]] [[イベント]]内で同期的にページ遷移が開始されることはありません。
[11] [[prompt to unload a document]] は ⊿ を指定した[[履歴の探索]]や、
[CODE(JS)@en[[[window.open]]]] や、[[閲覧文脈を閉じる]]際にも呼び出されます。
[12] [[prompt to unload a document]] が呼び出された場合、 refuse
されていなければ、その後 [[unload a document]] が呼び出されることになります。
* [CODE(DOMi)@en[BeforeUnloadEvent]] インターフェイス
[15] [DFN[[CODE(DOMi)@en[[[BeforeUnloadEvent]]]]]] [[インターフェイス]] [SRC[>>13]]
は、 [CODE(DOMe)@en[[[beforeunload]]]] [[イベント]]で使われます。
[17] [CODE(DOMi)@en[[[BeforeUnloadEvent]]]] [[インターフェイス]]は、
[[文書環境]]に[[晒され]]ています [SRC[>>13]]。
[16] [CODE(DOMi)@en[[[BeforeUnloadEvent]]]] [[インターフェイス]]は、
[CODE(DOMi)@en[[[Event]]]] [[インターフェイス]]を[[継承]]しています [SRC[>>13]]。
;; [18] 他の[[イベント]]インターフェイスとは違って、[[コンストラクター]]はありません。
[19] [CODE(DOMi)@en[[[BeforeUnloadEvent]]]] [[インターフェイス]]は、
[DFN[[CODE(DOMa)@en[[[returnValue]]]]]] [[IDL属性]]を持ちます [SRC[>>13]]。
;; 他の[[イベント]]インターフェイスの[[属性]]とは違って、読み書きの両方が可能です。
[20] [CODE(DOMa)@en[[[returnValue]]]] [[IDL属性]]は、 [CODE(DOMi)@en[[[DOMString]]]]
を設定、取得できる[[属性]]で、初期値は[[空文字列]]です [SRC[>>13]]。
[[イベントリスナー]]内で[[著者]]が適切な値を設定することが想定されていました。
[46] この[[IDL属性]]は、[[後方互換性]]のためのものです [SRC[>>13]]。
値が設定されているかどうかが処理に反映されますが、値そのものは無視されます。
[[著者]]は、 [CODE(DOMm)@en[preventDefault]] などを使う[SHOULD[べきです]] [SRC[>>13]]。
[HISTORY[
[21] [[prompt to unload a document]] は、
[[著者]]が [CODE(DOMa)@en[[[returnValue]]]] に非[[空文字列]]を設定したら、
それを[[モーダルダイアログ]]に表示することになっていました。
[22] [[IEのイベントモデル]]では、[[イベントハンドラー]]の[[返り値]]は[[イベント]]オブジェクトの
[CODE(DOMa)@en[[[returnValue]]]] を設定するのと同義でした。現在の [[DOM]]
では、唯一 [CODE(DOMi)@en[[[BeforeUnloadEvent]]]] にのみ [CODE(DOMa)@en[[[returnValue]]]]
が残っています。
]HISTORY]
* [CODE(DOMa)@en[onbeforeunload]] 属性
[14] [CODE(DOMa)@en[[[onbeforeunload]]]] [[イベントハンドラー属性]]は、
他の[[イベントハンドラー]]とは違って、[[返り値]]が[[イベント]]オブジェクトの
[CODE(DOMa)@en[[[returnValue]]]] [[IDL属性]]の値 (を[[文字列化]]したもの) に設定されます。
;; [[イベントハンドラー]]参照。
* 歴史
[1] [CITE[Re: salvaging work while navigating away from a web app -- onunload="confirm('save before quitting?')]] ([[Ian Hickson]] 著, [TIME[2008-12-12 08:55:08 +09:00]] 版) <http://permalink.gmane.org/gmane.org.w3c.whatwg.discuss/17107>
[2] [CITE@en[IEでのonBeforeUnload の挙動 | Inside ASCADE]] ([TIME[2009-02-20 05:46:35 +09:00]] 版) <http://inside.ascade.co.jp/node/58>
><a> タグの href で javascipt を呼び出した場合に location を変化させない(つもり)にもかかわらず、onBeforeunload イベントが発生したことです。ちなみにFirefoxではこの場合にイベントは発生しません。
>
- 多少仕様の記述と異なるが大体MSDNのドキュメント通り
- href="javascript:xx" でonBeforeunload が発生するのは少し困る
- document.close ではonBeforeunload が発生しないが別に困らない
[3] [CODE(DOMe)@en[[[beforeunload]]]] 内で [CODE(HTMLe)@en[[[img]]]] により [[fetch]] を行うと、
[[Chrome]] と [[IE10]] では実際にアクセスが発生しますが、 [[Firefox]] では発生しません。 [TIME[2013-07-04T03:05:58.500Z]]
[4] [CITE@en[Web Applications 1.0 r8282 OnBeforeUnloadEventHandler is supposed to allow null return values (and some markup error fixes, oops)]]
( ([TIME[2013-11-14 07:45:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=8281&to=8282>
[5] [CITE[IRC logs: freenode / #whatwg / 20150115]]
( ([TIME[2015-01-16 11:47:48 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20150115#l-693>
[23] [CITE[Update on standardizing shadow DOM and custom elements — Anne’s Blog]]
([TIME[2015-07-29 12:37:46 +09:00]] 版)
<https://annevankesteren.nl/2015/07/shadow-dom-custom-elements-update>
[24] [CITE[IRC logs: freenode / #whatwg / 20150727]]
([TIME[2015-07-30 10:13:04 +09:00]] 版)
<http://krijnhoetmer.nl/irc-logs/whatwg/20150727>
[25] [CITE@en[Block modal dialogs by default in sandboxed documents · whatwg/html@bbccfc9]] ([TIME[2015-09-10 00:20:23 +09:00]] 版) <https://github.com/whatwg/html/commit/bbccfc976754def0c187ac8ce5891d2fb20dfc15>
[37] [CITE@en[Remove the storage mutex due to lack of implementation · whatwg/html@1b918cf]] ([TIME[2015-12-16 14:38:10 +09:00]] 版) <https://github.com/whatwg/html/commit/1b918cf72fcbba011f83b92ab5d1f483fb1cafa3>
[38] [CITE@en[Allow truncation of alert/confirm/prompt text · whatwg/html@56f5c5e]]
([TIME[2016-02-21 12:50:32 +09:00]] 版)
<https://github.com/whatwg/html/commit/56f5c5e39b8b43b4bd4a8007fdc56ad797a5b2a7>
[44] [CITE@en[Ignore beforeunload event return value · whatwg/html@01d9870]]
([TIME[2016-04-09 13:26:44 +09:00]] 版)
<https://github.com/whatwg/html/commit/01d9870a6873e6d6410c3abf9fe38533646631b9>