[4] [DFN[[RUBYB[[[イベントリスナー]]]@en[event listener]]]]は特定の[[イベント]]に[[コールバック]]を関連付けるものです [SRC[>>3]]。 

;; [27] [[イベントハンドラー]]とは異なります。[[イベントハンドラー]]は、
[[イベントリスナー]]の特殊形です。

* 仕様書

[REFS[
- [3] [CITE@en-US[DOM Standard]] ([TIME[2013-04-26 20:00:45 +09:00]] 版) <http://dom.spec.whatwg.org/#interface-eventtarget>
- [22] [CITE@en-US[DOM Standard]] ([TIME[2014-11-27 19:54:36 +09:00]] 版) <https://dom.spec.whatwg.org/#concept-event-listener-invoke>
]REFS]

* 状態

[5] [[イベントリスナー]]は、次のもので構成されます。
[FIG(list members)[
:[F[[RUBYB[[[イベント型]]]@en[event type]]]] [SRC[>>3]]:
[[コールバック]]を呼び出すべき[[イベント型]]です。文字列で1つだけ指定できます。
:[F[[RUBYB[[[コールバック]]]@en[callback]]]] [SRC[>>3]]:
実際に呼び出される[[コールバック関数]]です。
[CODE(DOMi)@en[EventListener]] に相当する [[JavaScript]] [[関数オブジェクト]]か、
[[イベントハンドラー]]の[[ラッパー]]に当たる[[イベントハンドラー処理アルゴリズム]]の[[関数]]のいずれかです。
:[F[[RUBYB[[[捕獲]]]@en[capture]]]] [SRC[>>3]]:
[[コールバック]]を[[捕獲]]段階で呼び出すべきなら[[真]]、[[bubble]] 段階で呼び出すべきなら[[偽]]のフラグです。
: [F[[RUBYB[[[受動的]]]@en[passive]]]] :
[[イベント]]を[[取消]]する可能性があるかどうかを指定します。
[[利用者エージェント]]はこの情報を処理の最適化のために使うことができます。
: [F[一度のみ]] :
一度実行した後に削除されるべきかどうかを指定します。
:[F[[RUBYB[削除済みフラグ]@en[removed flag]]]] [SRC[>>3]]:
[CODE(DOMm)@en[[[removeEventListener]]]] で削除されたかどうかを表します。
]FIG]

** 辞書

[32] [DFN[[CODE(DOMi)@en[EventListenerOptions]]]] [SRC[>>3]] は、
[CODE(DOMm)@en[addEventListener]] と [CODE(DOMm)@en[removeEventListener]]
で[[イベントリスナー]]の指定に補助的に用いる[[辞書]]です。
次の[[メンバー]]があります。
[FIG(list members)[
: [CODE(DOMa)@en[capture]] : [F[捕獲]]を指定する [CODE(IDL)@en[boolean]] の値です。
]FIG]

[33] [DFN[[CODE(DOMi)@en[AddEventListenerOptions]]]] は、
[CODE(DOMm)@en[addEventListener]] で[[イベントリスナー]]の指定に補助的に用いる[[辞書]]です。
[CODE(DOMi)@en[EventListenerOptions]] を[[継承]]しています [SRC[>>3]]。
次の追加の[[メンバー]]があります。
[FIG(list members)[
: [CODE(DOMa)@en[passive]] : [F[受動的]]を指定する [CODE(IDL)@en[boolean]] の値です。
: [CODE(DOMa)@en[once]] : [F[一度のみ]]を指定する [CODE(IDL)@en[boolean]] の値です。
]FIG]

* [CODE(DOMi)@en[EventListener]]

[6] [CODE(IDL)@en[[[callback interface]]]] である [DFN[[CODE(DOMi)@en[[[EventListener]]]]]]
は、[[イベントリスナー]]として登録する[[コールバック]]のための[[インターフェイス]]です。

[7] [[JavaScript]] では [CODE(DOMi)@en[[[Function]]]] を直接[[コールバック]]として使うことができます。

;; [28] [[JavaScript]] ではほとんどすべての場合、この形が採られます。

[8] [[オブジェクト]]を[[コールバック]]として使う[[言語束縛]]では、
[DFN[[CODE(DOMm)@en[[[handleEvent]]]]]] [[メソッド]]を持ったオブジェクトとする必要があります。

[9] いずれにせよ、[[コールバック]]には [CODE(DOMi)@en[[[Event]]]] が1つ引数として引き渡されます。

[HISTORY[
[10] [[DOM2]] や [[DOM3]] 初期は [[WebIDL]] を使っていなかったので、通常の
[CODE(IDL)@en[[[interface]]]] として定義されていました。そのため >>8 のようになっています。

[53] なおこの [CODE[handleEvent]]
という[[演算]]名は、
他の[[コールバックインターフェイス]]にも踏襲されていました。
]HISTORY]

[11] この [CODE(DOMi)@en[[[EventListener]]]] は >>5 の[[イベント・リスナー]]の定義における[[コールバック]]として使われることになります。
[CODE(DOMi)@en[[[EventListener]]]] 自体は[[イベント・リスナー]]でないことになりますが、
この用語のずれは歴史的経緯によるもの [SRC[>>3]] と説明されています。

* 例外

[23] [[イベントリスナー]]内部で発生し[[捕捉]]されていない[[例外]]があった場合、
[[Webブラウザー]]は[[例外を報告]]します [SRC[>>22]]。

[24] [[例外を報告]]しても[[ディスパッチ]]の処理は継続されます。
他の[[イベントリスナー]]の処理は影響を受けません。

* イベントリスナーリスト

[26] [[イベント対象]]の[[オブジェクト]]は、[DFN[[F[[RUBYB[[[イベントリスナーリスト]]]@en[event listener list]]]]]]
[SRC[>>3]] を持ちます。
[CODE(DOMm)@en[[[addEventListener]]]] によってここに[[イベントリスナー]]を追加したり、
[CODE(DOMm)@en[[[removeEventListener]]]] によりここから削除したりできます。

[51] 次の[[演算]]があります。

[FIG(short list)[ [52] [[イベントリスナー]]の[[演算]]
- [[イベントリスナーを追加]]
- [[イベントリスナーを削除]]
- [[全イベントリスナー群を削除]]
]FIG]

[HISTORY[
[60] 含まれている[[イベントリスナー]]の一覧を取得したり、
含まれているかチェックしたりはできません。
[[DOM3イベント]]で提案されていましたが、用途がないとして削除されました。
]HISTORY]

** イベントリスナーによる動作の変化

[13] [[イベントリスナー]]によって [[Webブラウザー]]の挙動が変化することがあります。
例えば[[デバイス]]の動作に関する[[イベント]]は、当該[[イベントリスナー]]が一つも登録されていなければ、
[[発火]]してもしなくても変わらないので、[[発火]]しないことによって電力消費や処理時間を節約できるかもしれません。
このような[[文書]]からも[[利用者]]からもまったく観測できない変化は別として、
次のような[[利用者]]から観測可能な変化が規定されています。

;; [21] [[著者]]からは観測できません。

;; [29] [CODE[[[passive]]]] も参照。

[FIG(list)[
- [14] [[unstyled document]] の定義
-- [[イベント・リスナー]]が登録されていれば、 [[unstyled document view]] は使われません。
- [15] [[bfcache]] の利用可能性
- [16] [CODE(DOMi)@en[[[EventSource]]]] の[[ごみ収集]]
- [17] [[[CODE(DOMi)@en[WebSocket]]のごみ収集]]
- [19] [CODE(DOMi)@en[[[Notification]]]] の[[ごみ収集]]
-- [20] [CITE@en-US[Notifications API Standard]] ([TIME[2014-02-11 16:20:34 +09:00]] 版) <http://notifications.spec.whatwg.org/#garbage-collection>
- [42] [CODE(DOMi)@en[BroadcastChannel]] の[[ごみ収集]]
- [[サービスワーカーを走らせる]]処理
- [[文書のunload]]
]FIG]

[40] [[著者]]からも[[利用者]]からも直接は観測できない (もしかすると[[利用者]]からは何らかの表示で観測できるかもしれない) ものの例としては、次のものがあります。
[FIG(list)[
- [41] 必要な場合のみ、[[センサー]]を動作させる
-- [CODE[deviceorientation]], [CODE[deviceorientationabsolute]]
-- [CODE[devicemotion]]
]FIG]

* 関連

[12] [[イベントハンドラー]]も参照。

* 歴史

[REFS[
-[1] [CITE[IRC logs: freenode / #whatwg / 20120319]]
( ([TIME[2012-03-25 22:53:56 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20120319>
-[2] [CITE['''['''whatwg''']''' Detecting eventListeners]]
([TIME[2012-06-14 09:13:58 +09:00]] 版)
<http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-June/036398.html>
- [25] [CITE@en[If an event listener callback throws, report the exception (window.onerr... · 55f7dbf · whatwg/dom]] ([TIME[2014-11-30 14:49:15 +09:00]] 版) <https://github.com/whatwg/dom/commit/55f7dbf200bfb63a26f66a3875dc6f9d402c7728>
]REFS]

[18] [CITE[IRC logs: freenode / #whatwg / 20140409]]
( ([TIME[2014-04-10 13:28:16 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140409>

** [CODE(DOMi)@en[EventListenerOptions]]

[35] [CITE@en[EventListenerOptions]]
([TIME[2015-07-06 23:03:09 +09:00]] 版)
<http://rbyers.github.io/EventListenerOptions/EventListenerOptions.html>

[36] [CITE@en[''''''[''''''whatwg'''''']'''''' DOM Events Proposal: EventListenerOptions 'mayCancel' for  improved scroll performance]]
([[Rick Byers]] 著, [TIME[2015-07-09 04:12:36 +09:00]] 版)
<https://lists.w3.org/Archives/Public/public-whatwg-archive/2015Jul/0018.html>


[30] [CITE@en[Define that event listener capture/passive fields default to false · whatwg/dom@1ff10ba]]
([TIME[2016-02-25 11:29:33 +09:00]] 版)
<https://github.com/whatwg/dom/commit/1ff10baeafd55e4b4877d642ca8658e11e60d10b>

[31] [CITE@en[Enable an event listener to be invoked just once · whatwg/dom@e002d78]]
([TIME[2016-04-25 18:22:50 +09:00]] 版)
<https://github.com/whatwg/dom/commit/e002d7811533e276c9927b237748c4e170f4cb10>

[34] [CITE@en[Remove passive as event listener key · whatwg/dom@a13a3c7]]
([TIME[2016-04-25 21:19:29 +09:00]] 版)
<https://github.com/whatwg/dom/commit/a13a3c7fc14732691b50c51316b16de0915a61f2>

[37] [CITE@en[Editorial: define defaults for EventListenerOptions · whatwg/dom@2185b63]]
([TIME[2016-04-27 12:24:11 +09:00]] 版)
<https://github.com/whatwg/dom/commit/2185b636b7c12cb338f527e9ec8ab7c7d0554d26>

[38] [CITE@en[EventListenerOptions and passive event listeners - move to WICG? - APIs - WICG]]
([TIME[2016-07-27 11:54:54 +09:00]])
<https://discourse.wicg.io/t/eventlisteneroptions-and-passive-event-listeners-move-to-wicg/1386>

[39] [CITE@en[Align upload event dispatch with implementations]]
([[annevk]]著, [TIME[2016-08-11 22:59:34 +09:00]])
<https://github.com/whatwg/xhr/commit/667d4f3604aaee4e24bde33ed487cf8a98274e70>

[43] [CITE@en[Editorial: add note about event listeners causing preflight]]
([[sideshowbarker]]著, [TIME[2017-08-10 18:14:18 +09:00]])
<https://github.com/whatwg/xhr/commit/b1fd4d2d85be818adeb38a283e33b23a7152c170>

[44] [CITE@en[Editorial: simplify EventListenerOptions processing]]
([[annevk]]著, [TIME[2017-08-18 01:38:11 +09:00]])
<https://github.com/whatwg/dom/commit/cd3bcaeea40b4b9355ae7be3a5799813faa492fc>

[45] [CITE@en[Editorial: simplify EventListenerOptions processing by annevk · Pull Request #492 · whatwg/dom]]
([TIME[2017-08-18 14:05:26 +09:00]])
<https://github.com/whatwg/dom/pull/492>

[46] [CITE@en[Editorial: add "add an event listener" hook]]
([[annevk]]著, [TIME[2018-03-14 17:40:36 +09:00]])
<https://github.com/whatwg/dom/commit/2bdabb15de8112d9783cf393a3d6c37911149f77>

[47] [CITE@en[Editorial: add "add an event listener" hook by annevk · Pull Request #596 · whatwg/dom]]
([TIME[2018-03-18 00:15:48 +09:00]])
<https://github.com/whatwg/dom/pull/596>

[48] [CITE@en[Make event handlers share a code path with addEventListener()]]
([[annevk]]著, [TIME[2018-03-14 17:42:19 +09:00]])
<https://github.com/whatwg/html/commit/9a2a66cd8f8ddfa4c35d784bcda5c080e82aad38>

[49] [CITE[Array.prototype.flatMap & Array.prototype.flatten]]
([TIME[2018-01-18 11:42:19 +09:00]])
<https://tc39.github.io/proposal-flatMap/>

[50] [CITE@en[#SmooshGate FAQ  |  Web  |  Google Developers]]
([TIME[2018-03-20 07:16:16 +09:00]])
<https://developers.google.com/web/updates/2018/03/smooshgate>