-
Notifications
You must be signed in to change notification settings - Fork 4
/
505.txt
270 lines (217 loc) · 14.6 KB
/
505.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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
* 仕様書
[REFS[
- [1] [CITE@en-US[DOM Standard]] ([TIME[2013-04-26 20:00:45 +09:00]] 版) <http://dom.spec.whatwg.org/#interface-eventtarget>
-- [3] [CITE@en-US[DOM Standard]] ([TIME[2013-04-26 20:00:45 +09:00]] 版) <https://dom.spec.whatwg.org/#dom-eventtarget-dispatchevent>
- [22] '''[CITE@en[DOM Standard]] ([TIME[2015-11-20 19:44:48 +09:00]] 版) <https://dom.spec.whatwg.org/#concept-event-dispatch>'''
]REFS]
* [CODE(DOMi)@en[EventTarget]] インターフェイス [CODE(DOMm)@en[dispatchEvent]] メソッド
[23] [CODE(DOMi)@en[[[EventTarget]]]] [[インターフェイス]]の
[DFN[[CODE(DOMm)@en[[[dispatchEvent]]]]]] [[メソッド]] [SRC[>>3]]
は、[[イベント]]を[[dispatch]]するものです。
[24] この[[メソッド]]は、次のようにしなければ[['''なりません''']] [SRC[>>3]]。
[FIG(steps)[
= [25] [VAR[イベント]]を、必須の第1[[引数]]を [CODE(DOMi)@en[[[Event]]]]
と解釈したものに設定します。
= [26] [VAR[イベント]]の[F[[[ディスパッチフラグ]]]]が設定されているか、
[VAR[イベント]]の[F[[[初期化フラグ]]]]が設定されていないなら、
== [27] [CODE(DOMe)@en[[[InvalidStateError]]]] [[例外]]を[[投げ]]て停止します。
= [28] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[isTrusted]]]]]] を、
[[偽]]に設定します。
= [29] [VAR[イベント]]について[[ディスパッチ]]を実行し、
その結果を返します。
=- [30] この[[メソッド]]の返す値は、 [CODE(IDL)@en[[[boolean]]]] です。
]FIG]
;; [4] [[発火]]とは [CODE(DOMm)@en[[[isTrusted]]]] [[属性]]の扱いが違っています。
* ディスパッチ
[31] [DFN[[RUBYB[ディスパッチ]@en[dispatch]]]]は、
[[引数]][VAR[[RUBYB[[[イベント]]]@en[event]]]]、[VAR[[RUBYB[[[対象]]]@en[target]]]]、
[VAR[[RUBYB[[[対象上書き]]]@en[target override]]]]について、
次のようにしなければ[['''なりません''']] [SRC[>>22]]。
[FIG(steps)[
= [32] [VAR[イベント]]の[F[[[ディスパッチフラグ]]]]を設定します。
= [33] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[target]]]]]] を、
[VAR[対象上書き]]が指定されていればそれ、なければ[VAR[対象]]に設定します。
= [70] [VAR[イベント経路]]を、[VAR[対象]]のみを含む[[リスト]]に設定します。
= [34] [VAR[親]]を、[VAR[イベント経路]]の[F[最後の項目]]の[F[[[親の取得]]]]を[VAR[イベント]]について実行した結果に設定します。
= [69] [VAR[親]]が null でなければ、
[VAR[イベント経路]]の末尾に[VAR[親]]を追加し、
前の段階 (>>34) に戻ります。
= [73] [VAR[イベント経路]]から[F[最初の項目]]を削除します。
= [35] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[eventPhase]]]]]] を、
[CODE[[[CAPTURING_PHASE]]]] に設定します。
= [36] [VAR[イベント経路]]上の各員[VAR[オブジェクト]]について、最後から順に、
[VAR[オブジェクト]]についての処理 (>>37) を実行します。
= [39] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[eventPhase]]]]]] を、
[CODE[[[AT_TARGET]]]] に設定します。
= [40] [VAR[対象]]についての処理 (>>37) を実行します。
= [41] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[bubbles]]]]]] が[[真]]なら、
== [43] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[eventPhase]]]]]] を、
[CODE[[[BUBBLING_PHASE]]]] に設定します。
== [42] [VAR[イベント経路]]上の各員[VAR[オブジェクト]]について、最初から順に、
[VAR[オブジェクト]]についての処理 (>>37) を実行します。
= [44] [VAR[イベント]]の[F[[[ディスパッチフラグ]]]]を未設定とします。
= [45] [VAR[イベント]]の [F[[CODE(DOMa)@en[eventPhase]]]] を、
[CODE[[[NONE]]]] に設定します。
= [46] [VAR[イベント]]の [F[[CODE(DOMa)@en[currentTarget]]]] を、
[[null]] に設定します。
= [47] [VAR[イベント]]の[F[取り消しフラグ]]が設定されていれば[[偽]]、
されていなければ[[真]]を返します。
]FIG]
[71] つまり、まず[[イベント]]の[[対象]]から[[祖先]]に向けた[[木]]上の[[オブジェクト]]のリストを取得してから、
その各[[オブジェクト]]について[[イベントリスナー]]を実行します。
[[イベントリスナー]]の実行は、[[祖先]]から[[対象]]に向かう[[捕獲]]と、
[[対象]]から[[祖先]]に向かう [[bubbles]] の2段階に分かれます。
[[イベントリスナー]]内で[[親子]]関係が操作されても、
[[イベント]]の処理には影響を与えません。
;; [[イベント親]]も参照。
[37] ここで、[VAR[オブジェクト]]についての処理とは、
[VAR[イベント]]について次のようにすることをいいます [SRC[>>22]]。
[FIG(steps)[
= [38] [VAR[イベント]]の[F[[[伝播停止フラグ]]]]が設定されていれば、ここで停止します。
= [48] [VAR[オブジェクト]]を[DFN[[RUBYB[呼び出し]@en[invoke]]]]します。すなわち:
== [49] [VAR[リスナー群]]を、[VAR[オブジェクト]]の[F[[[イベントリスナー]]群]]の複製とします。
== [50] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[currentTarget]]]]]] を、
[VAR[オブジェクト]]に設定します。
== [78] [VAR[発見]]を、[VAR[オブジェクト]]と[VAR[リスナー群]]と[VAR[イベント]]に関して [[inner invoke]] を実行した結果に設定します。
== [81] [VAR[発見]]が[[偽]]なら、
=== [82] [VAR[元のイベント型]]を、[VAR[イベント]]の[F[[CODE(DOMa)@en[[[type]]]]]]
に設定します。
=== [85] [VAR[元のイベント型]]の[[遺物イベント型]]があれば、
==== [84] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[type]]]]]] を、
[VAR[元のイベント型]]の[[遺物イベント型]]に設定します。
==== [86] [VAR[オブジェクト]]と[VAR[リスナー群]]と[VAR[イベント]]に関して [[inner invoke]] を実行します。
==== [83] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[type]]]]]] を、
[VAR[元のイベント型]]に設定します。
]FIG]
[79] [VAR[オブジェクト]]と[VAR[リスナー群]]と[VAR[イベント]]に関する [DFN[[[inner invoke]]]]
は、次のようにします [SRC[>>22]]。
[FIG(steps)[
= [77] [VAR[発見]]を、[[偽]]に設定します。
= [51] [VAR[リスナー群]]の[[イベントリスナー]][VAR[リスナー]]について順に、
== [54]
[FIG(list)[
- [52] [VAR[リスナー]]の[F[[[削除済みフラグ]]]]が設定されておらず、かつ
- [59] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[type]]]]]]と[VAR[リスナー]]の[F[[[型]]]]が等しい
]FIG]
... なら、
=== [76] [VAR[発見]]を、[[真]]に設定します。
=== [60]
[FIG(list)[
- [56] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[eventPhase]]]]]]
が [CODE[[[CAPTURING_PHASE]]]] で[VAR[リスナー]]の[F[[[捕獲]]]]フラグが[[偽]]、または
- [55] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[eventPhase]]]]]]
が [CODE[[[BUBBLING_PHASE]]]] で[VAR[リスナー]]の[F[[[捕獲]]]]フラグが[[真]]
]FIG]
... なら、
==== [65] [VAR[リスナー]]の[F[[[受動的]]]]フラグが設定されていれば、
===== [92] [VAR[イベント]]の[F[[[受動的リスナー内フラグ]]]]を設定します。
==== [57] [VAR[リスナー]]の[F[[[コールバック]]]]の
[F[[CODE(DOMm)@en[[[handleEvent]]]] [[メソッド]]]]を実行します。
([VAR[イベント]]) を[[引数]]とし、
[VAR[イベント]]の [F[[CODE(DOMa)@en[[[currentTarget]]]]]] を[[コールバックthis値]]とします。
==== [58] 前項で[[例外]]が[[投げ]]られたなら、
[[例外を報告]]します。
==== [66] [VAR[イベント]]の[F[受動的リスナー内フラグ]]を消去します。
==== [93] [VAR[リスナー]]の[F[一度のみ]]フラグが設定されていれば、
===== [94] [VAR[リスナー]]の[F[削除済み]]フラグを設定します。
===== [95] [VAR[リスナー]]を、[VAR[オブジェクト]]の[F[[[イベントリスナー]]群]]から削除します。
==== [53] [VAR[イベント]]の[F[即時伝播停止フラグ]]が設定されていれば、
===== [89] [VAR[発見]]を返し、ここで停止します。
= [80] [VAR[発見]]を返します。
]FIG]
[61] この手続きより、
[CODE(DOMm)@en[[[addEventListener]]]] によって新たに[[イベントリスナー]]を追加しても、
その[[イベント]]の同じ [CODE(DOMa)@en[[[currentTarget]]]] の実行中は、
実行されません。
逆に [CODE(DOMm)@en[[[removeEventListener]]]] による[[イベントリスナー]]の削除は、
即時反映されます。
[62] [CODE(DOMm)@en[[[stopPropagation]]]] も、
その[[イベント]]の同じ [CODE(DOMa)@en[[[currentTarget]]]] の実行中は反映されません。
[CODE(DOmm)@en[[[stopImmediatePropagation]]]] は即時反映されます。
* 結果
[9] [[ディスパッチ]]した[[イベント]]が[[キャンセル]]されるかどうかで、その後の動作が変わることがあります。
[10] [[ディスパッチ]]によって[[イベントリスナー]]が実行されたかどうかで、その後の動作が変わることがあります。
[EG[
[12] [[prompt to unload a document]] は、 [CODE(DOMe)@en[[[beforeunload]]]]
の[[イベントリスナー]]が実行されたかどうかで動作が変わります。
]EG]
[EG[
[13] [[unload a document]] は、 [CODE(DOMe)@en[[[unload]]]]
の[[イベントリスナー]]が実行されたかどうかで動作が変わります。
]EG]
* 関連
[5] [[イベント親]]も参照。
* 歴史
** IE4 DOM
[19] [[IE事象モデル]]には [CODE(DOMm)@en[[[dispatchEvent]]]] と似たものとして
[CODE(DOMm)@en[[[fireEvent]]]] がありました。
;; [CODE(DOMm)@en[[[fireEvent]]]] の項を参照。
** W3C DOM
[20] [[DOM3]] までは[[ディスパッチ]]と[[発火]]は同義としていました。
;; 現在の [[DOM Standard]] では区別されています。
[21] [CITE[XML Events 2]]
( ([TIME[2010-12-18 05:25:20 +09:00]] 版))
<http://www.w3.org/TR/xml-events2/#section-dispatchEvent-element>
** DOM Standard
[2] [CITE@en[Re: '''['''dom-events''']''' dispatchEvent()ing a UA-dispatched event]]
([[Stewart Brodie]] 著, [TIME[2010-05-06 18:18:38 +09:00]] 版)
<http://lists.w3.org/Archives/Public/www-dom/2010AprJun/0042.html>
[18] [CITE@en[Bug 12230 – Some synthetic events cause actions]]
( ([TIME[2014-05-24 06:34:51 +09:00]] 版))
<https://www.w3.org/Bugs/Public/show_bug.cgi?id=12230>
[6] [CITE[Allow passing a target override to the dispatch algorithm. · d0f2c0b · whatwg/dom]]
( ([TIME[2013-11-13 11:39:36 +09:00]] 版))
<https://github.com/whatwg/dom/commit/d0f2c0bbc940061ac2a4623553de5c26409cce96>
[7] [CITE@en[Web Applications 1.0 r8271 Use DOM's hooks for defining the magic 'load' event in The End]]
( ([TIME[2013-11-13 06:44:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=8270&to=8271>
[8] [CITE[Allow passing a target override to the dispatch algorithm. · d0f2c0b · whatwg/dom]]
( ([TIME[2013-12-27 06:48:21 +09:00]] 版))
<https://github.com/whatwg/dom/commit/d0f2c0bbc940061ac2a4623553de5c26409cce96>
[11] [CITE@en[Check dispatch flag before initializing https://www.w3.org/Bugs/Public/s... · ccacdec · whatwg/dom]]
( ([TIME[2014-10-22 02:06:34 +09:00]] 版))
<https://github.com/whatwg/dom/commit/ccacdec1b3c99019677e8737c8f8550583984e67>
[14] [CITE@en[Clean up the event dispatch algorithms · whatwg/dom@d8cb495]]
([TIME[2015-11-23 17:49:13 +09:00]] 版)
<https://github.com/whatwg/dom/commit/d8cb49567c7018d4f9cfddf30fbc24f40693a9b0>
[15] [CITE@en[Fix the incorrect side effects of dispatch' target override · whatwg/dom@b8a8eb2]]
([TIME[2015-11-23 17:49:21 +09:00]] 版)
<https://github.com/whatwg/dom/commit/b8a8eb272d1ff3c654b3c5ae690c990f1d0cd700>
[16] [CITE@en[Fix #84: event listeners can be removed but not added during invocation · whatwg/dom@02710dd]]
([TIME[2015-11-23 17:49:26 +09:00]] 版)
<https://github.com/whatwg/dom/commit/02710dd77e89586ad78b9bce0a3b6fe5f9b2ad19>
* メモ
[17] [CITE@en-us[element.dispatchEvent - MDC Doc Center]]
( ([TIME[2010-12-30 21:50:11 +09:00]] 版))
<https://developer.mozilla.org/ja/DOM/element.dispatchEvent>
[63] [CITE@en[Check for "stop immediate propagation flag" earlier in invoke (no nor… · whatwg/dom@1cce4fd]]
([TIME[2016-02-15 00:21:28 +09:00]] 版)
<https://github.com/whatwg/dom/commit/1cce4fd5e39ac48c047d9de3d5efefc0a909db14>
[64] [CITE@en[Add EventListenerOptions and passive event listener feature · whatwg/dom@253a21b]]
([TIME[2016-02-15 00:21:40 +09:00]] 版)
<https://github.com/whatwg/dom/commit/253a21b8e78e37447c47983916a7cf39c4f6a3c5>
[67] [CITE@en[Integrate HTML's monkey patch to the event path · whatwg/dom@2d7b637]]
([TIME[2016-02-19 18:38:19 +09:00]] 版)
<https://github.com/whatwg/dom/commit/2d7b637b31fc6bad8f6c4743fb61016392fac382>
[68] [CITE@en[Remove event path monkey patch · whatwg/html@dad854e]]
([TIME[2016-02-19 18:38:25 +09:00]] 版)
<https://github.com/whatwg/html/commit/dad854e4c1f5f7098a1b1ec7f33e2218796f7442>
[72] [CITE@en[Fix #169: do not invoke target while iterating eventPath · whatwg/dom@26f7947]]
([TIME[2016-02-21 12:09:22 +09:00]] 版)
<https://github.com/whatwg/dom/commit/26f7947dce80934f75e0b399a40c444132e2ab9b>
[74] [CITE@en[Check for "stop immediate propagation flag" earlier in invoke (no nor… · whatwg/dom@1cce4fd]]
([TIME[2016-02-12 14:47:29 +09:00]] 版)
<https://github.com/whatwg/dom/commit/1cce4fd5e39ac48c047d9de3d5efefc0a909db14>
[75] [CITE@en[Fix #156: add legacy event type check to invoke algorithm · whatwg/dom@a026ccf]] ([TIME[2016-02-21 15:49:41 +09:00]] 版) <https://github.com/whatwg/dom/commit/a026ccf3efa8d34fb0cac580928f61d18b1e9f76>
[87] [CITE@en[Clarify EventTarget.dispatchEvent() · whatwg/dom@59d283a]]
([TIME[2016-02-27 11:44:45 +09:00]] 版)
<https://github.com/whatwg/dom/commit/59d283ab9c5d2e3dd823bca21eecaaaca402b181>
[88] [CITE@en[Properly check event's stop immediate propagation flag in "inner invoke" · whatwg/dom@b7a94a2]]
([TIME[2016-03-02 16:27:36 +09:00]] 版)
<https://github.com/whatwg/dom/commit/b7a94a2d90b37330ae9a5e5a125ce9047f867e42>
[90] [CITE@en[Editorial: check stop propagation flag at start of invoke · whatwg/dom@a768d8e]]
([TIME[2016-04-22 18:28:03 +09:00]] 版)
<https://github.com/whatwg/dom/commit/a768d8eef0584ea8ee831895b5c9dc8bcf363afc>
[91] [CITE@en[Enable an event listener to be invoked just once · whatwg/dom@e002d78]]
([TIME[2016-04-25 18:36:19 +09:00]] 版)
<https://github.com/whatwg/dom/commit/e002d7811533e276c9927b237748c4e170f4cb10>