@@ -104,6 +104,8 @@ urlPrefix: https://html.spec.whatwg.org/multipage/
104
104
text: effective script origin
105
105
text: origin alias; url: #concept-origin-alias
106
106
text: Unicode serialization of an origin; url: #unicode-serialisation-of-an-origin
107
+ urlPrefix: infrastructure.html
108
+ text: in parallel
107
109
urlPrefix: https://w3c.github.io/webcomponents/spec/shadow/
108
110
type: dfn; urlPrefix: #dfn-
109
111
text: shadow root
@@ -613,7 +615,7 @@ Lets look at an example of how <a>events</a> work in a <a>tree</a>:
613
615
function test(e) {
614
616
debug(e.target, e.currentTarget, e.eventPhase)
615
617
}
616
- document.addEventListener("hey", test, true)
618
+ document.addEventListener("hey", test, {capture: true} )
617
619
document.body.addEventListener("hey", test)
618
620
var ev = new Event("hey", {bubbles:true})
619
621
document.getElementById("x").dispatchEvent(ev)
@@ -728,16 +730,15 @@ inherits from the {{Event}} interface.
728
730
729
731
<dt><code><var> event</var> . <a method for=Event lt="preventDefault()">preventDefault</a> ()</code>
730
732
<dd> If invoked when the
731
- {{Event/cancelable}} attribute value is true,
733
+ {{Event/cancelable}} attribute value is true, and while executing a listener
734
+ for the <var> event</var> with {{EventListenerOptions/passive}} set to false,
732
735
signals to the operation that caused <var> event</var> to be
733
736
<a>dispatched</a> that it needs to be
734
737
canceled.
735
738
736
739
<dt><code><var> event</var> . {{Event/defaultPrevented}} </code>
737
740
<dd> Returns true if
738
- {{Event/preventDefault()}} was invoked
739
- while the {{Event/cancelable}} attribute
740
- value is true, and false otherwise.
741
+ {{Event/preventDefault()}} was invoked successfully to indicate cancellation, and false otherwise.
741
742
742
743
<dt><code><var> event</var> . {{Event/isTrusted}} </code>
743
744
<dd> Returns true if <var> event</var> was
@@ -799,6 +800,7 @@ flags that are all initially unset:
799
800
<li> <dfn export for=Event>canceled flag</dfn>
800
801
<li> <dfn export for=Event>initialized flag</dfn>
801
802
<li> <dfn export for=Event>dispatch flag</dfn>
803
+ <li> <dfn export for=Event>in passive listener flag</dfn>
802
804
</ul>
803
805
804
806
The
@@ -817,7 +819,14 @@ must return the values they were initialized to.
817
819
The
818
820
<dfn method for=Event>preventDefault()</dfn>
819
821
method must set the <a>canceled flag</a> if the
820
- {{Event/cancelable}} attribute value is true.
822
+ {{Event/cancelable}} attribute value is true and
823
+ the <a>in passive listener flag</a> is unset.
824
+
825
+ <p class="note no-backref">
826
+ This means there are scenarios where invoking {{preventDefault()}} has no effect.
827
+ User agents are encouraged to log the precise cause in a developer console,
828
+ to aid debugging
829
+ </p>
821
830
822
831
The
823
832
<dfn attribute for=Event>defaultPrevented</dfn>
@@ -972,14 +981,19 @@ for historical reasons.
972
981
<pre class=idl>
973
982
[Exposed=(Window,Worker)]
974
983
interface EventTarget {
975
- void addEventListener(DOMString type, EventListener? callback, optional boolean capture = false );
976
- void removeEventListener(DOMString type, EventListener? callback, optional boolean capture = false );
984
+ void addEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options );
985
+ void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options );
977
986
boolean dispatchEvent(Event event);
978
987
};
979
988
980
989
callback interface EventListener {
981
990
void handleEvent(Event event);
982
991
};
992
+
993
+ dictionary EventListenerOptions {
994
+ boolean capture;
995
+ boolean passive;
996
+ };
983
997
</pre>
984
998
985
999
{{EventTarget}} is an object to which an
@@ -991,60 +1005,97 @@ occurred. Each {{EventTarget}} has an associated list of
991
1005
<p> An <dfn export id=concept-event-listener>event listener</dfn> can be used to observe a specific
992
1006
<a>event</a> .
993
1007
994
- <p> An <a>event listener</a> consists of a <b> type</b> , <b> callback</b> , and <b> capture </b> . An
1008
+ <p> An <a>event listener</a> consists of a <b> type</b> , <b> callback</b> , <b> capture </b> and <b> passive </b> . An
995
1009
<a>event listener</a> also has an associated <b> removed flag</b> , which is initially unset.
996
1010
997
1011
<p class="note no-backref"> The callback is named {{EventListener}} for historical reasons. As can be
998
1012
seen from the definition above, an <a>event listener</a> is a more broad concept.
999
1013
1000
1014
<dl class=domintro>
1001
- <dt><code><var> target</var> . <a method lt="addEventListener()">addEventListener</a> (<var> type</var> , <var> callback</var> [, <var>capture </var> = false ] )</code>
1015
+ <dt><code><var> target</var> . <a method lt="addEventListener()">addEventListener</a> (<var> type</var> , <var> callback</var> [, <var>options </var>] )</code>
1002
1016
<dd>
1003
1017
Appends an <a>event listener</a> for <a>events</a> whose {{Event/type}} attribute value
1004
1018
is <var> type</var> . The <var> callback</var> argument sets the <b> callback</b> that will
1005
- be invoked when the <a>event</a> is <a>dispatched</a> . When set to true,
1006
- the <var> capture</var> argument prevents <b> callback</b> from being invoked when
1019
+ be invoked when the <a>event</a> is <a>dispatched</a> .
1020
+
1021
+ The <var> options</var> argument sets listener-specific options. For compatibility this can be
1022
+ just a boolean, in which case the method behaves exactly as if the value was
1023
+ specified as <var> options</var> ' <code> capture</code> member.
1024
+
1025
+ When set to true, <var> options</var> ' <code> capture</code> member prevents <b> callback</b>
1026
+ from being invoked when
1007
1027
the <a>event</a> 's {{Event/eventPhase}} attribute value is {{Event/BUBBLING_PHASE}} .
1008
- When false, <b> callback</b> will not be invoked when <a>event</a> 's {{Event/eventPhase}}
1028
+ When false (or not present) , <b> callback</b> will not be invoked when <a>event</a> 's {{Event/eventPhase}}
1009
1029
attribute value is {{Event/CAPTURING_PHASE}} . Either way, <b> callback</b> will be
1010
1030
invoked if <a>event</a> 's {{Event/eventPhase}} attribute value is {{Event/AT_TARGET}} .
1011
1031
1032
+ When set to true, <var> options</var> ' <code> passive</code> member indicates that the <b> callback</b>
1033
+ will not cancel the event by invoking {{preventDefault()}} .
1034
+ This is used to enable performance optimizations described in [[#observing-event-listeners]] .
1035
+
1012
1036
The <a>event listener</a> is appended to <var> target</var> 's list of
1013
1037
<a>event listeners</a> and is not appended if it is a duplicate, i.e., having the same
1014
- <b> type</b> , <b> callback</b> , and <b> capture </b> values.
1038
+ <b> type</b> , <b> callback</b> , <b> capture </b> and <b> passive </b> values.
1015
1039
1016
- <dt><code><var> target</var> . <a method lt="removeEventListener()">removeEventListener</a> (<var> type</var> , <var> callback</var> [, <var>capture </var> = false ] )</code>
1040
+ <dt><code><var> target</var> . <a method lt="removeEventListener()">removeEventListener</a> (<var> type</var> , <var> callback</var> [, <var>options </var>] )</code>
1017
1041
<dd> Remove the <a>event listener</a>
1018
1042
in <var> target</var> 's list of
1019
1043
<a>event listeners</a> with the same
1020
1044
<var> type</var> , <var> callback</var> , and
1021
- <var> capture </var> .
1045
+ <var> options </var> .
1022
1046
1023
1047
<dt><code><var> target</var> . <a method lt="dispatchEvent()">dispatchEvent</a> (<var> event</var> )</code>
1024
1048
<dd> <a>Dispatches</a> a synthetic event <var> event</var> to <var> target</var> and returns
1025
1049
true if either <var> event</var> 's {{Event/cancelable}} attribute value is false or its
1026
1050
{{Event/preventDefault()}} method was not invoked, and false otherwise.
1027
1051
</dl>
1028
1052
1053
+ <p> To <dfn export for=Event id=concept-flatten-options>flatten</dfn> <var> options</var> run these steps:
1054
+
1055
+ <ol>
1056
+ <li> Let <var> capture</var> and <var> passive</var> be false.
1057
+
1058
+ <li> If <var> options</var> is a boolean, set <var> capture</var> to
1059
+ <var> options</var> .
1060
+
1061
+ <li> If <var> options</var> is a dictionary and <code> {{EventListenerOptions/capture}} </code> is
1062
+ present in <var> options</var> with value true, then set <var> capture</var> to true.
1063
+
1064
+ <li> If <var> options</var> is a dictionary and <code> {{EventListenerOptions/passive}} </code> is
1065
+ present in <var> options</var> with value true, then set <var> passive</var> to true.
1066
+
1067
+ <li> Return <var> capture</var> and <var> passive</var> .
1068
+ </ol>
1069
+
1029
1070
<p> The
1030
- <dfn method for=EventTarget><code>addEventListener(<var>type</var>, <var>callback</var>, <var>capture </var>)</code></dfn>
1071
+ <dfn method for=EventTarget><code>addEventListener(<var>type</var>, <var>callback</var>, <var>options </var>)</code></dfn>
1031
1072
method, when invoked, must run these steps:
1032
1073
1033
1074
<ol>
1034
1075
<li><p> If <var> callback</var> is null, terminate these steps.
1035
1076
1077
+ <li> Let <var> capture</var> and <var> passive</var> be the result of <a>flattening</a> <var> options</var> .
1078
+
1036
1079
<li><p> Append an <a>event listener</a> to the associated list of <a>event listeners</a> with
1037
- <b> type</b> set to <var> type</var> , <b> callback</b> set to <var> callback</var> , and <b> capture</b>
1038
- set to <var> capture</var> , unless there already is an <a>event listener</a> in that list with the
1039
- same <b> type</b> , <b> callback</b> , and <b> capture</b> .
1080
+ <b> type</b> set to <var> type</var> , <b> callback</b> set to <var> callback</var> , <b> capture</b>
1081
+ set to <var> capture</var> , and <b> passive</b> set to <var> passive</var> unless there
1082
+ already is an <a>event listener</a> in that list with the same <b> type</b> ,
1083
+ <b> callback</b> , <b> capture</b> , and <b> passive</b> .
1040
1084
</ol>
1041
1085
1042
1086
<p> The
1043
- <dfn method for=EventTarget><code>removeEventListener(<var>type</var>, <var>callback</var>, <var>capture</var>)</code></dfn>
1044
- method, when invoked, must, if there is an <a>event listener</a> in the associated list of
1045
- <a>event listeners</a> whose <b> type</b> is <var> type</var> , <b> callback</b> is <var> callback</var> ,
1046
- and <b> capture</b> is <var> capture</var> , set that <a>event listener</a> 's <b> removed flag</b> and
1047
- remove it from the associated list of <a>event listeners</a> .
1087
+ <dfn method for=EventTarget><code>removeEventListener(<var>type</var>, <var>callback</var>, <var>options</var>)</code></dfn>
1088
+ method, when invoked, must, run these steps
1089
+
1090
+ <ol>
1091
+ <li> Let <var> capture</var> and <var> passive</var> be the result of <a>flattening</a> <var> options</var> .
1092
+
1093
+ <li> If there is an <a>event listener</a> in the associated list of
1094
+ <a>event listeners</a> whose <b> type</b> is <var> type</var> , <b> callback</b> is <var> callback</var> ,
1095
+ <b> capture</b> is <var> capture</var> , and <b> passive</b> is <var> passive</var> then
1096
+ set that <a>event listener</a> 's <b> removed flag</b> and remove it from the
1097
+ associated list of <a>event listeners</a> .
1098
+ </ol>
1048
1099
1049
1100
<p> The <dfn method for=EventTarget><code>dispatchEvent(<var>event</var>)</code></dfn> method, when
1050
1101
invoked, must run these steps:
@@ -1059,6 +1110,32 @@ invoked, must run these steps:
1059
1110
</ol>
1060
1111
1061
1112
1113
+ <h3 id=observing-event-listeners>Observing event listeners</h3>
1114
+
1115
+ <p> In general, developers do not expect the presence of an <a>event listener</a> to be
1116
+ observable. The impact of an <a>event listener</a> is determined by its <b> callback</b> .
1117
+ That is, a developer adding a no-op <a>event listener</a> would not expect it to have
1118
+ any side effects.
1119
+
1120
+ <p> Unfortunately, some event APIs have been designed such that implementing them
1121
+ efficiently requires observing <a>event listeners</a> . This can make the presence
1122
+ of listeners observable in that even empty listeners can have a dramatic performance impact
1123
+ on the behavior of the application. For example, touch and wheel events which can be used to block
1124
+ asynchronous scrolling. In some cases this problem can be mitigated by specifying
1125
+ the event to be {{Event/cancelable}} only when there is at least one
1126
+ non-{{EventListenerOptions/passive}} listener. For example, non-{{EventListenerOptions/passive}}
1127
+ {{TouchEvent}} listeners must block scrolling, but if all listeners are {{EventListenerOptions/passive}} then
1128
+ scrolling can be allowed to start <a>in parallel</a> by making the {{TouchEvent}}
1129
+ uncancelable (so that calls to {{Event/preventDefault()}} are ignored). So code
1130
+ dispatching an event is able to observe the absence of non-{{EventListenerOptions/passive}}
1131
+ listeners, and use that to clear the {{Event/cancelable}} property of the event
1132
+ being dispatched.
1133
+
1134
+ <p> Ideally, any new event APIs are defined such that they do not need this
1135
+ property (use
<a href="https://lists.w3.org/Archives/Public/public-script-coord/">[email protected] </a>
1136
+ for discussion).
1137
+
1138
+
1062
1139
<h3 id=dispatching-events>Dispatching events</h3>
1063
1140
1064
1141
<p> To <dfn export for=Event id=concept-event-dispatch>dispatch</dfn> an <var> event</var> to a
@@ -1139,9 +1216,14 @@ invoked, must run these steps:
1139
1216
<var> listener</var> 's <b> capture</b> is true, terminate these substeps (and run them for the next
1140
1217
<a>event listener</a> ).
1141
1218
1219
+ <li> If <var> listener</var> 's <b>passive</b> is true, set <var>event</var>' s <a>in passive listener flag</a> .
1220
+
1142
1221
<li><p> Call <var> listener</var> 's <b>callback</b>' s {{EventListener/handleEvent()}} , with
1143
1222
<var> event</var> as argument and <var> event</var> 's {{Event/currentTarget}} attribute value as
1144
1223
<a>callback this value</a> . If this throws any exception, <a>report the exception</a> .
1224
+
1225
+ <li> Clear <var> event</var> 's <a>in passive listener flag</a> .
1226
+
1145
1227
</ol>
1146
1228
</ol>
1147
1229
@@ -9073,6 +9155,7 @@ Peter Sharpe,
9073
9155
Philip Jägenstedt,
9074
9156
Philippe Le Hégaret,
9075
9157
Rafael Weinstein,
9158
+ Rick Byers,
9076
9159
Rick Waldron,
9077
9160
Robbert Broersma,
9078
9161
Robin Berjon,
0 commit comments