/
505.txt
277 lines (220 loc) · 14.8 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
271
272
273
274
275
276
277
* 仕様書
[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[イベント]]、[VAR[対象]]、[VAR[対象上書き]]について[[イベント経路]]を構築します。
= [35] [VAR[イベント]]の[F[相]]を、[CODE[[[CAPTURING_PHASE]]]] に設定します。
= [36] [VAR[イベント経路]]上の各[VAR[項目]]について、最後から順に、
== [45] [VAR[項目]]の[F[対象]]と[F[現在対象]]が異なるなら、
=== [34] [VAR[イベント]]の[VAR[項目]]についての処理 (>>37) を実行します。
= [42] [VAR[イベント経路]]上の各[VAR[項目]]について、最初から順に、
== [39] [VAR[項目]]の[F[対象]]と[F[現在対象]]が異なるなら、
=== [41] [VAR[イベント]]の [F[[CODE(DOMa)@en[[[bubbles]]]]]] が[[真]]なら、
==== [43] [VAR[イベント]]の[F[相]]を、 [CODE[BUBBLING_PHASE]] に設定します。
==== [40] [VAR[イベント]]の[VAR[項目]]についての処理 (>>37) を実行します。
== [46] それ以外なら、
=== [69] [VAR[イベント]]の[F[相]]を、 [CODE[AT_TARGET]] に設定します。
=== [70] [VAR[イベント]]の[VAR[項目]]についての処理 (>>37) を実行します。
= [44] [VAR[イベント]]の欄を次の通り設定します。
[FIG(list members)[
: [F[ディスパッチフラグ]] : [[偽]]
: [F[現在対象]] : [CODE[null]]
: [F[相]] : [CODE[NONE][eventPhase]]
: [F[経路][イベント経路]] : [[空]]
]FIG]
= [47] [VAR[イベント]]の[F[取り消しフラグ]]が設定されていれば[[偽]]、
されていなければ[[真]]を返します。
]FIG]
[71] つまり、まず[[イベント]]の[[対象]]から[[祖先]]に向けた[[木]]上の[[オブジェクト]]のリストを取得してから、
その各[[オブジェクト]]について[[イベントリスナー]]を実行します。
[[イベントリスナー]]の実行は、[[祖先]]から[[対象]]に向かう[[捕獲]]と、
[[対象]]から[[祖先]]に向かう [[bubbles]] の2段階に分かれます。
[[イベントリスナー]]内で[[親子]]関係が操作されても、
[[イベント]]の処理には影響を与えません。
;; [[イベント親]]、[[相]]も参照。
[37] ここで、[VAR[イベント]]の[VAR[項目]]についての処理とは、
次のようにすることをいいます ([DFN[[RUBYB[呼び出し]@en[invoke]]]]) [SRC[>>22]]。
[FIG(steps)[
= [73] [VAR[イベント]]の[F[対象][イベント対象]]を、
[VAR[項目]]の[F[対象][イベント経路]]に設定します。
= [38] [VAR[イベント]]の[F[[[伝播停止フラグ]]]]が設定されていれば、ここで停止します。
= [50] [VAR[イベント]]の[F[現在対象]]を、[VAR[項目]]の[F[現在対象][イベント経路]]に設定します。
= [49] [VAR[リスナー群]]を、[VAR[項目]]の[F[対象][イベント対象]]の[F[[[イベントリスナー]]群]]の複製とします。
= [78] [VAR[発見]]を、[VAR[項目]]の[F[対象][イベント対象]]と[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[項目]]の[F[対象][イベント対象]]と[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]
... なら、
==== [93] [VAR[リスナー]]の[F[一度のみ]]フラグが設定されていれば、
===== [95] [VAR[リスナー]]を、[VAR[オブジェクト]]の[F[[[イベントリスナー]]群]]から削除します。
==== [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[受動的リスナー内フラグ]]を消去します。
==== [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>
[96] [CITE@en[Address reentrancy issue with "once" listeners]]
([[annevk]]著, [TIME[2016-06-08 01:51:48 +09:00]])
<https://github.com/whatwg/dom/commit/5324200d70eb23276cb58b814416e19c436104f2>
[48] [CITE@en[Shadow: define event retargeting for shadow trees]]
([[annevk]]著, [TIME[2016-04-29 21:04:07 +09:00]])
<https://github.com/whatwg/dom/commit/ed94c9f2f1850b2e6a9b357c6870186859da4c2d>
[94] [CITE@en[Rename scoped to composed and invert its meaning]]
([[annevk]]著, [TIME[2016-05-10 16:14:09 +09:00]])
<https://github.com/whatwg/dom/commit/6e1b0386644301859c697ee2e868313963d2a602>